您的位置:首页 > 其它

SOCKET简单实例

2007-08-21 16:04 225 查看
客户端

WSAStartup→socket→サービス指定→connect→send→closesocket→WSACleanup


#define TCP_FLG 1


#define UDP_FLG 0


#define PORT_IP_REMOCON (60000)


#define IP_SERVER ("192.168.168.113")


#define MAX_LENGTH 100




static SOCKET g_socket = INVALID_SOCKET;


static SOCKADDR_IN g_sockaddr ;


static char g_command[MAX_LENGTH];




void main()...{


int ret = 0;


memset(&g_command,0,sizeof(g_command));




CreateSocket(TCP_FLG);


printf("スレーブが起動しました、送信データをご入力ください。use →~closesocket~close SendData --");




while(1)...{


gets(&g_command);




if (strcmp(&g_command,"closesocket") == 0)...{


CloseSocket();


break;


}


else




...{


SendData();


}


printf("SendData --");


}


exit(1);


}






int CreateSocket(int protocol)...{


int type ;


int sts ;


int error_no = 0;


WSADATA wsData;


WSAStartup(MAKEWORD(2, 2),&wsData);




memset(&g_sockaddr, 0, sizeof(g_sockaddr));


g_sockaddr.sin_addr.s_addr = inet_addr(IP_SERVER);


//表示在Internet域中使用


g_sockaddr.sin_family = AF_INET;


//将主机的unsigned long????网?字??序(32位):


g_sockaddr.sin_port = htons(PORT_IP_REMOCON);






if (protocol == TCP_FLG )...{


type = SOCK_STREAM;




}else if(protocol == UDP_FLG)...{


type = SOCK_DGRAM;


}




g_socket = socket(AF_INET,type,0);




if (g_socket == SOCKET_ERROR )...{


error_no = WSAGetLastError();


return -1;


}




sts = connect(g_socket, (struct SOCKADDR_IN *)&g_sockaddr , (int)sizeof(g_sockaddr));




if (sts < 0 )...{


error_no = WSAGetLastError();


return -2;


}






}






int SendData(void)...{


send(g_socket,&g_command,sizeof(g_command),0);


}






void CloseSocket(void)...{


closesocket(g_socket);


g_socket =INVALID_SOCKET;


WSACleanup();


}

服务器(单线程)

WSAStartup→socket→bind→listen→accept→recv→closesocket→WSACleanup


#define TCP_FLG 1


#define UDP_FLG 0


#define SERVER_PORT 60000


#define SERVER_IP ("192.168.168.113")


#define STDIN 0 /* file descriptor for standard input */


static SOCKET g_socket = INVALID_SOCKET;


static SOCKET g_client_socket ;


static SOCKADDR_IN g_sockaddr ;






void main()...{


int sts = 0;


sts = CreateSocket(TCP_FLG);




if (sts == -1)...{


printf("起動失敗。");


}


ReceiveData();


CloseSocket();


}






int CreateSocket(int type)...{


WSADATA wsaData;


int protocol;


int sts;


int nfds;






WSAStartup(MAKEWORD(2,2),&wsaData);






if(type == TCP_FLG )...{


protocol = SOCK_STREAM;




}else if (type == UDP_FLG)...{


protocol = SOCK_DGRAM;


}




g_socket = socket(AF_INET,protocol,0);


memset(&g_sockaddr, 0, sizeof(g_sockaddr));


g_sockaddr.sin_family = AF_INET;


g_sockaddr.sin_port = htons(SERVER_PORT);


g_sockaddr.sin_addr.S_un.S_addr = inet_addr(SERVER_IP);


bind(g_socket,(SOCKADDR_IN *)&g_sockaddr,sizeof(g_sockaddr));


sts = listen(g_socket,1);


printf("マスタを起動します............. ");


}






int ReceiveData(void)...{


char g_receive[100];


int addrlen = (int)sizeof(g_sockaddr);






while(1)...{


g_client_socket = accept(g_socket,(SOCKADDR_IN*)&g_sockaddr,&addrlen);




if ((SOCKET)g_client_socket != INVALID_SOCKET )...{


printf("連続が入りました............. ");


break;


}


Sleep(2000);


break;


}




memset(&g_receive, 0, sizeof(g_receive));




while(1)...{


recv(g_client_socket,&g_receive, sizeof(g_receive), 0);




if (strcmp(g_receive,"") != 0)...{


printf("%s データは取得しました。............. ",g_receive);


memset(&g_receive, 0, sizeof(g_receive));


}


Sleep(2000);


}


}






void CloseSocket(void)...{


closesocket(g_socket);


WSACleanup();


}

多线成

轮询"会使CPU处于忙等待方式,从而降低性能,浪费系统资源。而调用 select()会有效地解决这个问题,它允许你把进程本身挂起来,而同时使系统内核监听所要求的一组文件描述符的任何活动,只要确认在任何被监控的文件 描述符上出现活动,select()调用将返回指示该文件描述符已准备好的信息,从而实现了为进程选出随机的变化,而不必由进程本身对输入进行测试而浪费 CPU开销。Select函数原型为:
int select(int numfds,fd_set *readfds,fd_set *writefds,
fd_set *exceptfds,struct timeval *timeout);
   其中readfds、writefds、exceptfds分别是被select()监视的读、写和异常处理的文件描述符集合。如果你希望确定是否可以 从标准输入和某个socket描述符读取数据,你只需要将标准输入的文件描述符0和相应的sockdtfd加入到readfds集合中;numfds的值 是需要检查的号码最高的文件描述符加1,这个例子中numfds的值应为sockfd+1;当select返回时,readfds将被修改,指示某个文件 描述符已经准备被读取,你可以通过FD_ISSSET()来测试。为了实现fd_set中对应的文件描述符的设置、复位和测试,它提供了一组宏:
   FD_ZERO(fd_set *set)----清除一个文件描述符集;
   FD_SET(int fd,fd_set *set)----将一个文件描述符加入文件描述符集中;
   FD_CLR(int fd,fd_set *set)----将一个文件描述符从文件描述符集中清除;
   FD_ISSET(int fd,fd_set *set)----试判断是否文件描述符被置位。
   Timeout参数是一个指向struct timeval类型的指针,它可以使select()在等待timeout长时间后没有文件描述符准备好即返回。struct timeval数据结构为:
   struct timeval {
   int tv_sec; /* seconds */
   int tv_usec; /* microseconds */
};




void main()...{


WSADATA wsData;


fd_set readfds;


fd_set fds;


struct timeval tv;


int sts;




WSAStartup(MAKEWORD(2, 2),&wsData);


CreateSocket(TCP_FLG);


memset(&g_receive,0,sizeof(g_receive));




tv.tv_sec = 10;


tv.tv_usec = 5000000;




FD_ZERO(&readfds);


FD_SET(g_client_socket,&readfds);




while(1)...{


// memcpy(&fds, &readfds, sizeof(readfds));


sts = select(g_client_socket+1, &readfds, NULL, NULL, &tv);




if (FD_ISSET(g_client_socket,&readfds))...{




//g_client_socket = accept(g_socket,&g_sockaddr,&addlen);


recv(g_client_socket,&g_receive, sizeof(g_receive), 0);


FD_SET(g_client_socket,&readfds);


}


}


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: