[C語言] 基於Linux的一對一Socket簡易聊天程式例項
阿新 • • 發佈:2019-02-06
如題
此篇示例為Socket網路程式的基本範例,於LINUX環境下編譯並執行通過
使用方法請參閱程式碼,程式碼不復雜
chatclient.c
chatserver.c#include <stdio.h> #include <string.h> #include <errno.h> #include <sys/socket.h> #include <resolv.h> #include <stdlib.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <sys/time.h> #include <sys/types.h> #define MAXBUF 1024 int main(int argc, char *argv[]) { int s, len; struct sockaddr_in addr; char buffer[MAXBUF + 1]; fd_set afds, rfds; struct timeval tv; switch (argc) { case 3: break; default: printf("usage: chatclient ip port\n"); exit(1); } if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("socket error!\n"); return -1; } addr.sin_family = AF_INET; addr.sin_port = htons(atoi(argv[2])); bzero((void*)&addr.sin_zero,8); if(inet_aton(argv[1], (struct in_addr *) &addr.sin_addr.s_addr) == 0) { perror(argv[1]); exit(errno); } if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) != 0) { perror("Connect "); exit(errno); } printf("\nclient: ready for chatting!\n"); while(1) { int ret; FD_ZERO(&rfds); FD_ZERO(&afds); FD_SET(0, &afds); FD_SET(s, &afds); tv.tv_sec = 1; tv.tv_usec = 0; // set select time-out = 1s memcpy(&rfds, &afds, sizeof(rfds)); ret = select(s + 1, &rfds, (fd_set *)0, (fd_set *)0, &tv); if(ret < 0) { printf("client: select error %s", strerror(errno)); break; } else if(ret == 0) { continue; } else { if(FD_ISSET(0, &rfds)) //read user input process { bzero(buffer, MAXBUF + 1); fgets(buffer, MAXBUF, stdin); if(!strncasecmp(buffer, "quit", 4)) { printf("client: exit chatting!\n"); break; } len = send(s, buffer, strlen(buffer) - 1, 0); if(len < 0) { printf("client: send failed\n"); break; } else printf("client: %s\n",buffer); } if(FD_ISSET(s, &rfds)) //receive msg through socket { bzero(buffer, MAXBUF + 1); len = recv(s, buffer, MAXBUF, 0); if(len > 0) printf("client recv:'%s'\n",buffer); else { if(len < 0) printf("client: recv failed\n"); else printf("client: session end, because the other one quit\n"); break; } } } } close(s); return 0; }
/**************************************************/ /* Chat - Server */ /**************************************************/ #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/wait.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/time.h> #include <sys/types.h> #define MAXBUF 1024 #define QLEN 5 int main(int argc, char *argv[]) { fd_set afds, rfds; struct sockaddr_in addr_host, addr_client; int msock, ssock; socklen_t len; unsigned int port; char buf[MAXBUF + 1]; struct timeval tv; switch (argc) { case 2: port = atoi(argv[1]); break; default: printf("usage: chatserver port\n"); exit(1); } msock=socket(AF_INET,SOCK_STREAM,0); if(msock<0) { printf("socket error!\n"); return -1; } addr_host.sin_family = AF_INET; addr_host.sin_addr.s_addr=htonl(INADDR_ANY); addr_host.sin_port = htons(port); bzero((void *)&addr_host.sin_zero, 8); if(bind(msock,(struct sockaddr*)&addr_host,sizeof(addr_host))<0) { close(msock); printf("bind error!\n"); return -1; } if(listen(msock,QLEN)<0) { printf("LISTEN error"); return -1; } while(1) { printf("\nserver: waiting...\n"); len = sizeof(struct sockaddr); if((ssock =accept(msock, (struct sockaddr *) &addr_client, &len)) == -1) { perror("accept"); exit(errno); } else printf("server: got connection from %s, port %d, socket %d\n", inet_ntoa(addr_client.sin_addr), ntohs(addr_client.sin_port), ssock); printf("\nserver: ready for chatting!\n"); while(1) { int ret; FD_ZERO(&rfds); FD_ZERO(&afds); FD_SET(0, &afds); FD_SET(ssock, &afds); tv.tv_sec = 1; tv.tv_usec = 0; // set select time-out = 1s memcpy(&rfds, &afds, sizeof(rfds)); ret = select(ssock + 1, &rfds, (fd_set *)0, (fd_set *)0, &tv); if(ret < 0) { printf("server: select error %s", strerror(errno)); break; } else if(ret == 0) { continue; } else { if(FD_ISSET(0, &rfds)) //read user input process { bzero(buf, MAXBUF + 1); fgets(buf, MAXBUF, stdin); if(!strncasecmp(buf, "quit", 4)) { printf("server: exit chatting!\n"); break; } len = send(ssock, buf, strlen(buf) - 1, 0); if(len > 0) printf("server:%s\n",buf); else { printf("server:send failed\n"); break; } } if(FD_ISSET(ssock, &rfds)) //receive msg through socket { bzero(buf, MAXBUF + 1); len = recv(ssock, buf, MAXBUF, 0); if(len > 0) printf("server recv:'%s'\n",buf); else { if(len < 0) printf("server:recv failed\n"); else printf("server: session end, because the other one quit\n"); break; } } } } close(ssock); //decide whether continue chatting printf("Continue chatting?(no=>exit)"); fflush(stdout); bzero(buf, MAXBUF + 1); fgets(buf, MAXBUF, stdin); if(!strncasecmp(buf, "no", 2)) { printf("server: Terminating chat!\n"); break; } } close(msock); return 0; }