客户端
WSAStartup→socket→サービス指定→connect→send→closesocket→WSACleanup
#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 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 */
};
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);
}
}
}