Client:
#define _gnu_source 1#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <assert.h> #include <stdio.h> #include <unistd.h> #include <string.h > #include <stdlib.h> #include <poll.h> #include <fcntl.h> #define BUFFER_SIZE 64int Main () {const CH Ar *ip= "127.0.0.1"; int port=12345; struct sockaddr_in server_address; Bzero (&server_address,sizeof (server_address)); Server_address.sin_family=af_inet; Inet_pton (AF_INET,IP,&SERVER_ADDRESS.SIN_ADDR); Server_address.sin_port=htons (port); int Sockfd=socket (pf_inet,sock_stream,0); ASSERT (sockfd!=0); if (Connect (SOCKFD, (struct sockaddr *) &server_address,sizeof (server_address)) <0) {printf ("Connection fail Ed\n "); Close (SOCKFD); return 1; } struct POLLFD fds[2]; Fds[0].fd=0; fds[0].revents=0; FDS[1].FD=SOCKFD; Fds[1].events=pollin | Pollrdhup; fds[1].revents=0; Char Read_buf[buffer_size]; int pipefd[2]; int Ret=pipe (PIPEFD); ASSERT (Ret!=-1); while (1) {ret=poll (fds,2,-1); if (ret<0) {printf ("poll failure\n"); Break } if (Fds[1].revents&pollrdhup) {printf ("server close the connection\n"); Break } else if (Fds[1].revents&pollin) {memset (read_buf, ' + ', buffer_size); Recv (fds[1].fd,read_buf,buffer_size-1,0); printf ("%s\n", read_buf); } if (Fds[0].revents&pollin) {Ret=splice (0,null,pipefd[1],null,32768,splice_f_more | Splice_f_move); Ret=splice (Pipefd[0],null,sockfd,null,32768,splice_f_more | Splice_f_move); }} close (SOCKFD); return 0;}
Server:
#define _gnu_source 1#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <assert.h> #include <stdio.h> #include <unistd.h> #include <errno.h > #include <string.h> #include <fcntl.h> #include <stdlib.h> #include <poll.h> #define User_ LIMIT 5#define buffer_size 64#define fd_limit 65535struct client_data{struct sockaddr_in address; Char *write_buf; Char buf[buffer_size];}; int setnonblocking (int fd) {int old_option=fcntl (FD,F_GETFL); int New_option=old_option | O_nonblock; Fcntl (fd,f_setfl,new_option); return old_option;} int main () {const char *ip= "127.0.0.1"; int port=12345; int ret=0; int i,j; struct SOCKADDR_IN address; Bzero (&address,sizeof (address)); Address.sin_family=af_inet; Inet_pton (AF_INET,IP,&ADDRESS.SIN_ADDR); Address.sin_port=htons (port); Address.sin_addr.s_addr=inaddr_any; int Listenfd=socket (PF_INET,SOck_stream,0); ASSERT (listenfd>=0); Ret=bind (LISTENFD, (struct sockaddr *) &address,sizeof (address)); ASSERT (Ret!=-1); Ret=listen (listenfd,5); ASSERT (Ret!=-1); struct client_data* users= (struct client_data*) calloc (fd_limit,sizeof (struct client_data)); struct POLLFD fds[user_limit+1]; int user_counter=0; for (i=1;i<=user_limit;++i) {fds[i].fd=-1; fds[i].events=0; } FDS[0].FD=LISTENFD; Fds[0].events=pollin | Pollerr; fds[0].revents=0; while (1) {printf ("{\ n"); Ret=poll (fds,user_counter+1,-1); printf ("}\n"); if (ret<0) {printf ("poll failure\n"); Break } for (I=0;i<user_counter+1;++i) {if (FDS[I].FD==LISTENFD) && (Fds[i].revents&pollin ) {struct sockaddr_in client_address; socklen_t client_addrlengh=sizeof (client_address); int Connfd=accept (LISTENFD, (Struct SOCKADDR *) &client_address,&client_addrlengh); if (connfd<0) {printf ("errno is:%d\n", errno); Continue } if (user_counter>=user_limit) {const char *info= "too many users\n"; printf ("%s", info); Send (Connfd,info,strlen (info), 0); Close (CONNFD); Continue } user_counter++; users[connfd].address=client_address; Setnonblocking (CONNFD); FDS[USER_COUNTER].FD=CONNFD; Fds[user_counter].events=pollin | pollrdhup| Pollerr; fds[user_counter].revents=0; printf ("comes a new User,now has%d users\n", user_counter); } else if (Fds[i].revents&pollerr) {printf ("Get an error from%d \ n", FDS[I].FD); Char errors[100]; memset (Errors, ' 100 '); socklen_t length=sizeof (Errors); if (getsockopt (fds[i].fd,sol_socket,so_error,&errors,&length) <0) {printf ("get Socket option failed\n "); } continue; } else if (fds[i].revents&pollrdhup) {USERS[FDS[I].FD]=USERS[FDS[USER_COUNTER].FD ]; Close (FDS[I].FD); Fds[i]=fds[user_counter]; i--; user_counter--; printf ("A client left\n"); } else if (fds[i].revents&pollin) {int connfd=fds[i].fd; memset (users[connfd].buf, ' buffer_size-1 '); RET=RECV (connfd,users[connfd].buf,buffer_size-1,0); if (ret<0) {if (Errno!=eagain) {Close (connf D); USERS[FDS[I].FD]=USERS[FDS[USER_COUNTER].FD]; Fds[i]=fds[user_counter]; i--; user_counter--; }} else if (ret==0) {} else { for (J=1;J<=USER_COUNTER;++J) {if (FDS[J].FD==CONNFD) {continue; } fds[j].events |=~pollin; Fds[j].events |=pollout; Users[fds[j].fd].write_buf=users[connfd].buf; }}} and else if (fds[i].revents&pollout) {int connfd=fds[ I].FD; if (!USERS[CONNFD].WRITE_BUF) {continue; } ret=send (Connfd,users[connfd].write_buf,strlen (users[cONNFD].WRITE_BUF), 0); Users[connfd].write_buf=null; Fds[i].events |=~pollout; Fds[i].events |=pollin; }}} free (users); Close (LISTENFD); return 0;}
Poll functions for multi-user chat under Linux