//服务器端源码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #include <sys/time.h> #include <sys/select.h> #define BUF_SIZE 100 void error_handling(const char *msg) { printf(msg,stderr); exit(1); } int main(int argc,char *argv[]) { int serv_sock,clnt_sock; struct sockaddr_in serv_adr,clnt_adr; struct timeval timeout; fd_set reads,cpy_reads; socklen_t adr_sz; int fd_max,str_len,fd_num,i; char buf[BUF_SIZE]; if(argc!=2) { printf("Usage:%s <port>\n",argv[0]); exit(1); } serv_sock=socket(PF_INET,SOCK_STREAM,0); memset(&serv_adr,0,sizeof(serv_adr)); serv_adr.sin_family=AF_INET; serv_adr.sin_addr.s_addr=htonl(INADDR_ANY); serv_adr.sin_port=htons(atoi(argv[1])); if(bind(serv_sock,(struct sockaddr*)&serv_adr,sizeof(serv_adr))==-1) error_handling("bind() error"); if(listen(serv_sock,5)==-1) error_handling("listen() error"); FD_ZERO(&reads); FD_SET(serv_sock,&reads); fd_max=serv_sock; //调试语句 printf("serv_sock:%d \n",serv_sock); while(1) { cpy_reads=reads; timeout.tv_sec=5; timeout.tv_usec=5000; if((fd_num=select(fd_max+1,&cpy_reads,0,0,&timeout))==-1) //失败返回-1 break; if(fd_num==0) //超时返回0 continue; //调试语句 printf("fd_num: %d \n",fd_num); for(i=0;i<fd_max+1;++i) //成功返回大于0的数 { if(FD_ISSET(i,&cpy_reads)) { if(i==serv_sock) { adr_sz=sizeof(clnt_adr); clnt_sock=accept(serv_sock,(struct sockaddr*)&clnt_adr,&adr_sz); FD_SET(clnt_sock,&reads); //向reads位数组中注册与客户端连接的文件描述符 if(fd_max<clnt_sock) fd_max=clnt_sock; printf("connected client: %d \n",clnt_sock); } else //与客户端相连接的文件描述符 { str_len=read(i,buf,BUF_SIZE); if(str_len==0) //客户端传递了EOF,这时str_len才等于0 { FD_CLR(i,&reads); close(i); printf("closed client: %d \n",i); } else { write(i,buf,str_len); //echo } } } } } return 0; }
//客户端源码:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <sys/socket.h> #include <unistd.h> void error_handling(char *message) { printf("%s\n",message); exit(1); } const int MAXN=(1<<10); int main(int argc,char *argv[]) { int clnt_sock; struct sockaddr_in serv_adr; char msg[MAXN]; char store[MAXN]; int str_len,str_cnt; if(argc!=3) { printf("Usage %s <IP> <port>\n",argv[0]); exit(1); } clnt_sock=socket(PF_INET,SOCK_STREAM,0); //第一步 if(clnt_sock==-1) error_handling("socket() error"); memset(&serv_adr,0,sizeof(serv_adr)); //填写要连接的服务器端地址 serv_adr.sin_family=AF_INET; serv_adr.sin_addr.s_addr=inet_addr(argv[1]); //写成htonl(argv[1])就是错,因为htonl()函数的参数要求为unsigned long而argv[1]却是字符串 serv_adr.sin_port=htons(atoi(argv[2])); if(connect(clnt_sock,(struct sockaddr*)&serv_adr,sizeof(serv_adr))==-1) //第二步 error_handling("connect() error"); while(1) { printf("send message to server(input q/Q to exit):"); scanf("%s",msg); if(!strcmp(msg,"q")||!strcmp(msg,"Q")) break; str_len=write(clnt_sock,msg,strlen(msg)); str_cnt=0; while(str_cnt<str_len) { str_cnt+=read(clnt_sock,&store[str_cnt],MAXN-1); } store[str_cnt]=0; printf("%s\n",store); } close(clnt_sock); //关闭,不是很优雅 return 0; }