client 和 server 通讯实例(TCP协议使用 select 函数)

来源:互联网 发布:淘宝c店的运营方案 编辑:程序博客网 时间:2024/05/22 10:37

client 和 server 通讯实例(TCP协议使用 select 函数)

先用标准输入(键盘输入)演示 select 函数的使用:

/****** sample.c for Linux ******/ #include <stdio.h>#include <string.h>#include <sys/select.h>#define STDIN 0int main(){int  n, flag;char buf[80];fd_set fds;struct timeval tv;int fd = STDIN;printf("type \"eXit\" to exit.\n");flag = 1;while(1 == flag){tv.tv_sec=10;tv.tv_usec=0;FD_ZERO(&fds);FD_SET(fd,&fds);//[] switch(select(fd+1, &fds, NULL, NULL, &tv))switch(select(FD_SETSIZE, &fds, NULL, NULL, &tv)){case -1:  // select错误printf("返回错误。\n");flag = -1;break;case 0: //再次轮询printf("超时。\n");break;default:if(FD_ISSET(fd, &fds)) {fgets(buf, 20, stdin);n = strlen(buf);if('\n' == buf[n-1])buf[n-1] = '\0';printf("数据:%s\n", buf);if(0 == strcmp(buf, "eXit")) //退出程序?{flag = 0;break;}}break;}}return flag;}

执行结果示例:

[root@localhost ~]# ./sample
type "eXit" to exit.
asdf
数据:asdf
asdfg
数据:asdfg
sdf
数据:sdf
超时。
超时。
eXit
数据:eXit
[root@localhost ~]#


服务器端代码(Linux系统,TCP协议):

/****** server.c for Linux ******/ #include <stdio.h> #include <errno.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h>#define STDIN 0int main(int argc, char *argv[]) { int    n, flag;char   buf[1024];fd_set fds;struct timeval tv;struct sockaddr_in   client_addr; int    sockfd, fd, sin_size;int                  port; struct sockaddr_in   addr; int    fdstd = STDIN;if(argc != 3) { fprintf(stderr,"Usage:%s ipaddr port\a\n",argv[0]); return -1; } if((port = atoi(argv[2])) < 0) { fprintf(stderr,"Usage:%s ipaddr port\a\n",argv[0]); return -1; } bzero(&addr,sizeof(struct sockaddr_in)); addr.sin_family=AF_INET; addr.sin_addr.s_addr=inet_addr(argv[1]);//htonl(INADDR_ANY);  addr.sin_port=htons(port); if((sockfd=socket(AF_INET,SOCK_STREAM,0)) == -1) { fprintf(stderr,"Socket error:%s\n\a",strerror(errno)); return -1; } if(bind(sockfd,(struct sockaddr *)(&addr),sizeof(struct sockaddr)) == -1) { fprintf(stderr,"Bind error:%s\n\a",strerror(errno)); return -1; } if(listen(sockfd,5) == -1) { fprintf(stderr,"Listen error:%s\n\a",strerror(errno)); return -1; } sin_size=sizeof(struct sockaddr_in); fd = accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size);if(fd != -1) {printf("connection from %s, fd = %d\n", inet_ntoa(client_addr.sin_addr), fd); }else{ fprintf(stderr,"Accept error:%s\n\a",strerror(errno)); close(sockfd); return 0;}printf("recv \"eXit\" to exit.\n");flag = 1;while(1 == flag){tv.tv_sec=10;tv.tv_usec=0;FD_ZERO(&fds);FD_SET(fd,&fds);// switch(select(fd+1, &fds, NULL, NULL, &tv))switch(select(FD_SETSIZE, &fds, NULL, NULL, &tv)){case -1:  // select错误printf("返回错误。\n");flag = -1;break;case 0: //再次轮询printf("超时。\n");break;default:if(FD_ISSET(fd, &fds)) {// 接收TCP数据。n = recv(fd, buf, sizeof(buf), MSG_DONTWAIT); //非阻塞模式接收buf[n] = '\0';printf("from client[fd = %d]: %s\n", fd, buf); if(0 == strcmp(buf, "eXit")) //退出程序?{flag = 0;break;}}break;}}close(fd); close(sockfd); return 0;} 


服务端代码(Linux系统,UDP协议)

#include <stdio.h>#include <string.h>  #include <sys/types.h>  #include <sys/socket.h>  #include <netinet/in.h>  #include <arpa/inet.h>    int main(int argc, char *argv[])  {      int len;  int sockfd, port, sin_size;      struct sockaddr_in addr;   //服务器网络地址结构体      struct sockaddr_in remote_addr; //客户端网络地址结构体       char buf[1024];  //数据传送的缓冲区   if(argc != 3) { fprintf(stderr,"Usage:%s ipaddr port\a\n",argv[0]); return -1; } if((port = atoi(argv[2])) < 0) { fprintf(stderr,"Usage:%s ipaddr port\a\n",argv[0]); return -1; } bzero(&addr,sizeof(struct sockaddr_in)); addr.sin_family=AF_INET; addr.sin_addr.s_addr=inet_addr(argv[1]);//htonl(INADDR_ANY);  addr.sin_port=htons(port);           /*创建服务器端套接字--IPv4协议,面向无连接通信,UDP协议*/      if((sockfd=socket(PF_INET, SOCK_DGRAM, 0)) < 0)      {            perror("socket");          return -1;      }         /* 将套接字绑定到网络地址上 */      if (bind(sockfd,(struct sockaddr *)&addr,sizeof(struct sockaddr)) < 0)      {          perror("bind");          return -1;      }      sin_size=sizeof(struct sockaddr_in);      printf("waiting for a packet...\n");            if((len = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&remote_addr,&sin_size)) < 0)      {          perror("recvfrom");          return -1;      }      printf("received packet from %s:\n", inet_ntoa(remote_addr.sin_addr));      buf[len]='\0';      printf("contents: %s\n",buf);      close(sockfd);      return 0;  }  


客户端代码(Linux系统):

/****** client.c for Linux ******/ #include <stdio.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <sys/socket.h> int main(int argc, char *argv[]) { int n, sockfd; char buf[1024]; struct sockaddr_in server_addr; struct hostent *host; int    port; if(argc!=3) { fprintf(stderr,"Usage:%s serverIPaddr portNumber\a\n",argv[0]); return -1; } if((host=gethostbyname(argv[1]))==NULL) { fprintf(stderr,"Gethostname error\n"); return -1; } if((port=atoi(argv[2]))<0) { fprintf(stderr,"Usage:%s serverIPaddr portNumber\a\n",argv[0]); return -1; } if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) { fprintf(stderr,"Socket Error:%s\a\n",strerror(errno)); return -1; } bzero(&server_addr,sizeof(server_addr)); server_addr.sin_family=AF_INET; server_addr.sin_port=htons(port); server_addr.sin_addr=*((struct in_addr *)host->h_addr); if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1) { fprintf(stderr,"Connect Error:%s\a\n",strerror(errno));}else{printf("type \"eXit\" to exit.\n");while(1){// 接收标准输入数据。fgets(buf, sizeof(buf), stdin);n = strlen(buf);if('\n' == buf[n-1])buf[n-1] = '\0';if(send(sockfd, buf, strlen(buf), MSG_NOSIGNAL) < 0){fprintf(stderr,"send error:%s\n", strerror(errno)); break;}if(0 == strcmp(buf, "eXit")) //退出程序?break;}}close(sockfd); return 0; } 

客户端代码(Windows系统,需要 ws2_32.lib 库文件):

/****** client.c for Windows ******/#define WIN32_LEAN_AND_MEAN #include <winsock2.h> #include <stdlib.h> #include <stdio.h> #include <string.h> int main(int argc, char **argv) { intn;charbuf[1024]; char*ipaddr; unsigned shortport;  structsockaddr_inserver;  WSADATAwsaData; SOCKETconn_socket; if(argc!=3) { fprintf(stderr,"Usage:%s serverIPaddr portNumber\a\n",argv[0]); return -1; } if((port = atoi(argv[2])) <=0 ) { fprintf(stderr,"Usage:%s serverIPaddr portNumber\a\n",argv[0]); return -1; } if (WSAStartup(0x202,&wsaData) == SOCKET_ERROR) { fprintf(stderr,"WSAStartup failed with error %d\n",WSAGetLastError()); WSACleanup(); return -1; } ipaddr = argv[1]; memset(&server, 0, sizeof(server));server.sin_family=AF_INET; server.sin_port=htons(port);server.sin_addr.s_addr=inet_addr(ipaddr);conn_socket = socket(AF_INET, SOCK_STREAM, 0); /* Open a socket */ if (conn_socket < 0 ) { fprintf(stderr,"Client: Error Opening socket: Error %d\n", WSAGetLastError()); WSACleanup(); return -1; } if (connect(conn_socket,(struct sockaddr*)&server,sizeof(server)) == SOCKET_ERROR) { fprintf(stderr,"connect() failed: %d\n",WSAGetLastError()); WSACleanup(); return -1; } printf("type \"eXit\" to exit.\n");while(1){//fgets(buf, sizeof(buf), stdin);gets(buf);n = strlen(buf);if('\n' == buf[n-1])buf[n-1] = '\0';if(send(conn_socket, buf, strlen(buf), 0) < 0){fprintf(stderr,"send error:%s\n", strerror(errno)); break;}if(0 == strcmp(buf, "eXit"))break;}closesocket(conn_socket); WSACleanup(); return 0;}

执行结果示例:

--- 服务器端 ---

[root@localhost ~]# ./server 192.168.0.19 3560
connection from 192.168.0.19, fd = 4
recv "eXit" to exit.
from client[fd = 4]: sdf
超时。
超时。
from client[fd = 4]: 1234abc
超时。
from client[fd = 4]: eXit
[root@localhost ~]#

--- 客户端 ---

[root@localhost ~]# ./client 192.168.0.19 3560
type "eXit" to exit.
sdf
1234abc
eXit
[root@localhost ~]#




原创粉丝点击