Linux-聊天 socket程式設計
阿新 • • 發佈:2018-12-17
1對1聊天
通過select新增可讀事件的監聽實現。
服務端:
#include "header.h" int main(void) { int listenfd = -1; int connfd = -1; struct sockaddr_in server, client; int on = 1; memset(&server, 0, sizeof(server)); server.sin_family = AF_INET; server.sin_port = htons(8888); server.sin_addr.s_addr = htonl(INADDR_ANY); if (0 > (listenfd = socket(AF_INET, SOCK_STREAM, 0))) err_exit("socket"); setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); if (0 > bind(listenfd, (struct sockaddr *)&server, sizeof(server))) err_exit("bind"); listen(listenfd, 1024); printf("listen...\n"); memset(&client, 0, sizeof(client)); socklen_t len = sizeof(client); if (0 > (connfd = accept(listenfd, (struct sockaddr *)&client, &len))) err_exit("accept"); printf("client's ip is:%s, port is:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); char recv_buf[BUFSIZ]; char send_buf[BUFSIZ]; fd_set readfds; int maxfd = -1; int ret=-1; int i; while(1) { FD_ZERO(&readfds);//所有位置零 FD_SET(0, &readfds);//設定0位元位為1,用於傳送資料訊息通知 maxfd = maxfd > 0 ? maxfd : 0; FD_SET(connfd, &readfds);//設定connfd位元位為1,用於接受資料訊息通知, maxfd = maxfd > connfd ? maxfd : connfd; if (0 > select(maxfd + 1, &readfds, NULL, NULL, NULL))//設定被監聽的檔案描述符的總數為maxfd + 1,readfds可讀事件,且無限等待 err_exit("select"); for (i=0; i<=maxfd; i++) { if (FD_ISSET(i, &readfds)) //select返回後,用FD_ISSET測試給定位是否置位,通過獲取那個bit位就知道是那個連線有資料 { if (i == 0)//有資料需要傳送 { fgets(send_buf, sizeof(send_buf), stdin); if (0 > send(connfd, send_buf, strlen(send_buf) + 1, 0)) err_exit("send"); } else if (i == connfd)//有資料需要接收 { if (0 > (ret = recv(connfd, recv_buf, BUFSIZ, 0))) err_exit("recv"); else if (0 == ret) { printf("client quit!\n"); exit(0); } recv_buf[ret] = '\0'; printf("client: %s\n", recv_buf); } } } } close(listenfd); close(connfd); exit(0); }
客戶端:
#include "header.h" int main(void) { int connfd = -1; struct sockaddr_in server; memset(&server, 0, sizeof(server)); server.sin_family = AF_INET; server.sin_port = htons(8888); server.sin_addr.s_addr = inet_addr("192.168.1.50"); if (0 > (connfd = socket(AF_INET, SOCK_STREAM, 0))) err_exit("socket"); if (0 > connect(connfd, (struct sockaddr *)&server, sizeof(server))) err_exit("connect"); printf("connect success!\n"); char send_buf[BUFSIZ]; char recv_buf[BUFSIZ]; int maxfd= -1; fd_set readfds; int ret=-1; int i; while(1) { FD_ZERO(&readfds); FD_SET(0, &readfds); maxfd = maxfd > 0 ? maxfd : 0; FD_SET(connfd, &readfds); maxfd = maxfd > connfd ? maxfd : connfd; if (0 > select(maxfd + 1, &readfds, NULL, NULL, NULL)) err_exit("select"); for (i=0; i<=maxfd; i++) { if (FD_ISSET(i, &readfds)) { if (0 == i) { fgets(send_buf, sizeof(send_buf), stdin); if (0 > send(connfd, send_buf, strlen(send_buf) + 1, 0)) err_exit("send"); } else if (connfd == i) { if (0 > (ret = recv(connfd, recv_buf, BUFSIZ, 0))) err_exit("recv"); else if (0 == ret) { printf("server quit!\n"); exit(0); } recv_buf[ret] = '\0'; printf("server: %s\n", recv_buf); } } } } close(connfd); exit(0); }
1對多聊天
select-多路複用通訊