Linux C++ socket编程实例
文章目錄
- socket基本過程
- 基本的局域網聊天
- 局域網TCP服務器端
- 局域網TCP客戶端
- 客戶端服務端雙向異步聊天
- 異步聊天服務器端代碼
- 異步聊天客戶端代碼
- 局域網內服務端和有限個客戶端聊天
- 局域網TCP 2人聊天服務器端代碼
- 局域網TCP 2人聊天客戶端代碼
- 完美異步聊天服務端和客戶端
- 無限個客戶聊天的服務器端代碼
- 無限個客戶端連接的客戶端代碼
- 服務端:
服務器端初始化socket,然后與端口綁定,對端口進行監聽,調用accept阻塞,等待客戶端連接。
socket() -> bind() -> listen() -> accept() - 客戶端:
客戶端先初始化socket,然后與服務端連接,服務端監聽成功則連接建立完成。
socket() -> connect()
socket基本過程
- 服務端先創建一個套接字,端口綁定,對端口進行監聽,調用accept阻塞,等待客戶端連接。客戶端創建一個套接字,然后通過三次握手完成tcp連接后服務器端accept返回重新建立一個套接字代表返回客戶端的tcp連接,(在accept成功返回前有一個要注意的是server會有兩個隊列,一個存放完成三次握手的,一個是未完成三次握手的,每次accept會從完成三次握手的隊列中取出一個并一直建立TCP連接,此時才能算是真正的連接成功),完成上面的步驟后即可以開始數據的傳輸了,數據傳輸結束后再調用close關閉連接。
- 再說一下select函數在server和client雙向通信中的重要作用:網絡編程的過程中,經常會遇到許多阻塞的函數,網絡編程時使用的recv,recvfrom,connect函數都是阻塞的函數,當函數不能成功執行的時候,程序就會一直阻塞在這里,無法執行下面的代碼。select函數是一個輪值函數,即當循環詢問文件節點,可設置超時時間,超時時間到了就跳過代碼繼續往下執行。下面的第一個程序,如果不注釋掉server的send,那么如果server不想client發送信息則進程就會停頓在此處等待server發送無法執行下面的代碼,無法接受client發送來的消息,第二個程序就是對此進行的改進,在程序中引入select當超時后就會跳過當前代碼,執行下一步不會一直阻塞。(poll 和 epoll是對select的改進)
基本的局域網聊天
局域網TCP服務器端
實現的功能是client到server的半雙工通信,server只能接收client發送過來的消息,但是不能向client發送消息。
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #define QUEUE 20 //連接請求隊列int conn;int main() {printf("%d\n",AF_INET); //IPv4協議printf("%d\n",SOCK_STREAM); //字節流套接字int ss = socket(AF_INET, SOCK_STREAM, 0); //若成功則返回一個sockfd (套接字描述符)printf("%d\n", ss);struct sockaddr_in server_sockaddr; //一般是儲存地址和端口,用于信息的顯示及存儲作用//下面設置sockaddr_in 結構體中相關參數server_sockaddr.sin_family = AF_INET;server_sockaddr.sin_port = htons(PORT); //將一個無符號短整型數值轉換為網絡字節序,即大端模式printf("%d\n", INADDR_ANY);//INADDR_ANY就是指定地址為0.0.0.0的地址,這個地址事實上表示不確定地址,或"所有地址"、“任意地址”。//一般來說,在各個系統中均定義成為0值。server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY); //將主機無符號長整型數轉換成網絡字節順序。if(bind(ss, (struct sockaddr*)&server_sockaddr, sizeof(server_sockaddr)) == -1){perror("bind");exit(1);}if(listen(ss, QUEUE) == -1){perror("listen");exit(1);}struct sockaddr_in client_addr;socklen_t length = sizeof(client_addr);//成功返回非負描述字,出錯返回-1conn = accept(ss, (struct sockaddr*)&client_addr, &length);//如果accept成功,那么其返回值是由內核自動生成的一個全新描述符,代表與所返回客戶的TCP連接//accept之后就會用新的套接字connif( conn < 0 ){perror("connect");exit(1);}char buffer[1024];while(1){//這里把send注釋掉了,所以這個程序中server只能是接收client端的數據并能給client發送數據,即使不注釋掉也沒用,因為沒有對是否有數據>傳入和傳入//進行判斷所以按照下面的代碼這樣寫,每次都要先讓server輸入后才能輸出client傳過來的數據,若是server不輸入則程序無法向下走就沒有client發送過來的輸出,//而且每次顯示也只能是一行,這樣顯示就全是錯的了,所以就需要select和FD_ISSET的判斷了// memset(buf, 0 ,sizeof(buf));// if(fgets(buf, sizeof(buf),stdin) != NULL) {// send(conn, buf, sizeof(buf), 0); // }memset(buffer, 0, sizeof(buffer));int len = recv(conn, buffer, sizeof(buffer), 0); //從TCP連接的另一端接收數據。/*該函數的第一個參數指定接收端套接字描述符;第二個參數指明一個緩沖區,該緩沖區用來存放recv函數接收到的數據;第三個參數指明buf的長度;第四個參數一般置0*/if(strcmp(buffer, "exit\n") == 0)//如果沒有收到TCP另一端發來的數據則跳出循環不輸出{break;}printf("%s", buffer);//如果有收到數據則輸出數據//必須要有返回數據, 這樣才算一個完整的請求send(conn, buffer, len , 0);//向TCP連接的另一端發送數據。}close(conn); //因為accept函數連接成功后還會生成一個新的套接字描述符,結束后也需要關閉close(ss); //關閉socket套接字描述符return 0; }局域網TCP客戶端
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <sys/shm.h>#define PORT 6666 #define BUFFER_SIZE 1024/** 在TCP三次握手完成后會進入等待連接隊列,等待服務端調用accpet與之建立連接,這時候是server端調用accept跟客戶端建立 通信,客戶端并不需要調用accpet,因為有很多個客戶端要跟服務端建立連接,這時候服務端就會有一個隊列,對已經經過三次握 手的才可以建立連接(類似緩存信息),這個是由服務端來確認的,客戶端并不知道什么時候服務端才能跟它建立連接,在服務端 沒有調用accept與之連接或者還未排隊到它,只能是一直等待,直到服務端準備好了才能跟客戶端建立連接,所以主動權在服務端 */int main() {//定義 sockfdint sock_cli = socket(AF_INET, SOCK_STREAM, 0);//定義sockaddr_instruct sockaddr_in servaddr;servaddr.sin_family = AF_INET;servaddr.sin_port = htons(PORT); //服務器端口servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //服務器ip, inet_addr用于IPv4的IP轉換(十進制轉換為二進制)//127.0.0.1是本地預留地址//連接服務器, 成功返回0, 錯誤返回 -1if(connect(sock_cli, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0){perror("connect");exit(1);}char sendbuf[BUFFER_SIZE];char recvbuf[BUFFER_SIZE];while(fgets(sendbuf, sizeof(sendbuf), stdin) != NULL){//每次讀取一行,讀取的數據保存在buf指向的字符數組中,成功,則返回第一個參數 bufsend(sock_cli, sendbuf, strlen(sendbuf), 0); //發送if(strcmp(sendbuf, "exit\n") == 0)break;recv(sock_cli, recvbuf, sizeof(recvbuf), 0); //接收fputs(recvbuf, stdout);memset(sendbuf, 0, sizeof(sendbuf)); //接受或者發送完畢后把數組中的數據全部清空。 置 0memset(recvbuf, 0, sizeof(recvbuf));}close(sock_cli);return 0; }客戶端服務端雙向異步聊天
以上的局域網聊天應用有一個很重要的缺點, 服務器只能顯示客戶端發送的消息, 卻無法給客戶端發送消息, 這個很尷尬;
通過使用C中的select()函數, 實現一個異步聊天工具:
異步聊天服務器端代碼
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <sys/shm.h> #include <iostream> #define PORT 7000 #define QUEUE 20int main() {fd_set rfds;struct timeval tv;int retval, maxfd;int ss = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in server_sockaddr;server_sockaddr.sin_family = AF_INET;server_sockaddr.sin_port = htons(PORT);//printf("%d\n",INADDR_ANY);server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);if(bind(ss, (struct sockaddr* ) &server_sockaddr, sizeof(server_sockaddr))==-1){perror("bind");exit(1);}if(listen(ss, QUEUE) == -1){perror("listen");exit(1);}struct sockaddr_in client_addr;socklen_t length = sizeof(client_addr);///成功返回非負描述字,出錯返回-1int conn = accept(ss, (struct sockaddr*)&client_addr, &length);/*沒有用來存儲accpet返回的套接字的數組,所以只能實現server和單個client雙向通信*/if( conn < 0 ){perror("connect");exit(1);}while(1){/*把可讀文件描述符的集合清空*/FD_ZERO(&rfds);/*把標準輸入的文件描述符加入到集合中*/FD_SET(0, &rfds);maxfd = 0;/*把當前連接的文件描述符加入到集合中*/FD_SET(conn, &rfds);/*找出文件描述符集合中最大的文件描述符*/ if(maxfd < conn)maxfd = conn;/*設置超時時間*/tv.tv_sec = 5;//設置倒計時tv.tv_usec = 0;/*等待聊天*/retval = select(maxfd+1, &rfds, NULL, NULL, &tv);if(retval == -1){printf("select出錯,客戶端程序退出\n");break;}else if(retval == 0){printf("服務端沒有任何輸入信息,并且客戶端也沒有信息到來,waiting...\n");continue;}else{/*客戶端發來了消息*/if(FD_ISSET(conn,&rfds)){char buffer[1024]; memset(buffer, 0 ,sizeof(buffer));int len = recv(conn, buffer, sizeof(buffer), 0);if(strcmp(buffer, "exit\n") == 0) break;printf("%s", buffer);//send(conn, buffer, len , 0);把數據回發給客戶端}/*用戶輸入信息了,開始處理信息并發送*/if(FD_ISSET(0, &rfds)){char buf[1024];fgets(buf, sizeof(buf), stdin);//printf("you are send %s", buf);send(conn, buf, sizeof(buf), 0); }}}close(conn);close(ss);return 0; }異步聊天客戶端代碼
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <sys/shm.h>#define MYPORT 7000 #define BUFFER_SIZE 1024 int main() {int sock_cli;fd_set rfds;struct timeval tv;int retval, maxfd;///定義sockfdsock_cli = socket(AF_INET,SOCK_STREAM, 0);///定義sockaddr_instruct sockaddr_in servaddr;memset(&servaddr, 0, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(MYPORT); ///服務器端口servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); ///服務器ip//連接服務器,成功返回0,錯誤返回-1if (connect(sock_cli, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0){perror("connect");exit(1);}while(1){/*把可讀文件描述符的集合清空*/FD_ZERO(&rfds);/*把標準輸入的文件描述符加入到集合中*/FD_SET(0, &rfds);maxfd = 0;/*把當前連接的文件描述符加入到集合中*/FD_SET(sock_cli, &rfds);/*找出文件描述符集合中最大的文件描述符*/ if(maxfd < sock_cli)maxfd = sock_cli;/*設置超時時間*/tv.tv_sec = 5;tv.tv_usec = 0;/*等待聊天*/retval = select(maxfd+1, &rfds, NULL, NULL, &tv);if(retval == -1){printf("select出錯,客戶端程序退出\n");break;}else if(retval == 0){printf("客戶端沒有任何輸入信息,并且服務器也沒有信息到來,waiting...\n");continue;}else{/*服務器發來了消息*/if(FD_ISSET(sock_cli,&rfds)){char recvbuf[BUFFER_SIZE];int len;len = recv(sock_cli, recvbuf, sizeof(recvbuf),0);printf("%s", recvbuf);memset(recvbuf, 0, sizeof(recvbuf));}/*用戶輸入信息了,開始處理信息并發送*/if(FD_ISSET(0, &rfds)){char sendbuf[BUFFER_SIZE];fgets(sendbuf, sizeof(sendbuf), stdin);send(sock_cli, sendbuf, strlen(sendbuf),0); //發送memset(sendbuf, 0, sizeof(sendbuf));}}}close(sock_cli);return 0; }局域網內服務端和有限個客戶端聊天
以上的局域網聊天只能支持一個用戶, 我們還要改改, 必須是支持多用戶的聊天室:
局域網TCP 2人聊天服務器端代碼
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <fcntl.h> #include <sys/shm.h> #include <iostream> #include <thread> #include <stdlib.h>#define PORT 7000 #define QUEUE 20int ss;struct sockaddr_in client_addr; socklen_t length = sizeof(client_addr);int conns[2] = {}; //定義一個容量為2的數組來存放套接字,所以server最多只能跟兩個client通信 int z = 0;void thread_fn() {//成功返回非負描述字,出錯返回 -1int conn = accept(ss, (struct sockaddr*)&client_addr, &length);if( conn < 0){perror("connect");exit(1);}//把連接保存到臨時數組中;conns[z] = conn;z++;fd_set rfds;struct timeval tv;int retval, maxfd;while(1){/*把可讀文件描述符的集合清空*/FD_ZERO(&rfds);/*把標準輸入的文件描述符加入到集合中*/FD_SET(0, &rfds);maxfd = 0;/*把當前連接的文件描述符加入到集合中*/FD_SET(conn, &rfds);/*找出文件描述符集合中最大的文件描述符*/if(maxfd < conn){maxfd = conn;}/*設置超時時間*/tv.tv_sec = 5;tv.tv_usec = 0;/*等待聊天*/retval = select(maxfd + 1, &rfds, NULL, NULL, &tv);if(retval == -1){printf("select 出錯,客戶端程序退出\n");break;}else if(retval == 0){printf("服務器端沒有任何輸入信息,并且客戶端也沒有信息到來,waiting ...\n");continue;}else{/*客戶端發來了信息*/if(FD_ISSET(conn, &rfds)) //判斷conn是否在rfds中如果在返回非零,不在返回0{char buffer[1024];memset(buffer, 0 ,sizeof(buffer));//把buffer中的所有值賦值為0,即清空bufferint len = recv(conn, buffer, sizeof(buffer), 0);//把接收到的數據存放于buffer中printf("%s", buffer);}/*用戶輸入信息,開始處理信息并發送*/if(FD_ISSET(0, &rfds)){char buf[1024];fgets(buf, sizeof(buf), stdin);//每次讀取一行數據存放在buf中//printf("you are send %s", buf);for(int i=0; i<z; i++){send(conns[i], buf, sizeof(buf), 0);}}}}close(conn); }int main() {ss = socket(AF_INET, SOCK_STREAM, 0); //SOCK_STREAM即tcp協議,AF_INET是IPv4套接字struct sockaddr_in server_sockaddr;server_sockaddr.sin_family = AF_INET;server_sockaddr.sin_port = htons(PORT);//printf("%d\n",INADDR_ANY);server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);if(bind(ss, (struct sockaddr* ) &server_sockaddr, sizeof(server_sockaddr))==-1){perror("bind");exit(1);}if(listen(ss, QUEUE) == -1){perror("listen");exit(1);}std::thread t(thread_fn);std::thread t1(thread_fn); 這里把收發數據都存放在thread_fn中,所以創建一個這樣的線程就能使得server能多連接一個servert.join();t1.join();close(ss);return 0; }局域網TCP 2人聊天客戶端代碼
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <sys/shm.h>#define MYPORT 7000 #define BUFFER_SIZE 1024 int main() {int sock_cli;fd_set rfds;struct timeval tv;int retval, maxfd;///定義sockfdsock_cli = socket(AF_INET,SOCK_STREAM, 0);///定義sockaddr_instruct sockaddr_in servaddr;memset(&servaddr, 0, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(MYPORT); ///服務器端口servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); ///服務器ip//連接服務器,成功返回0,錯誤返回-1if (connect(sock_cli, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0){perror("connect");exit(1);}while(1){/*把可讀文件描述符的集合清空*/FD_ZERO(&rfds);/*把標準輸入的文件描述符加入到集合中*/FD_SET(0, &rfds);maxfd = 0;/*把當前連接的文件描述符加入到集合中*/FD_SET(sock_cli, &rfds);/*找出文件描述符集合中最大的文件描述符*/if(maxfd < sock_cli)maxfd = sock_cli;/*設置超時時間*/tv.tv_sec = 5;tv.tv_usec = 0;/*等待聊天*/retval = select(maxfd+1, &rfds, NULL, NULL, &tv);if(retval == -1){printf("select出錯,客戶端程序退出\n");break;}else if(retval == 0){printf("客戶端沒有任何輸入信息,并且服務器也沒有信息到來,waiting...\n");continue;}else{/*服務器發來了消息*/if(FD_ISSET(sock_cli,&rfds)){char recvbuf[BUFFER_SIZE];int len;len = recv(sock_cli, recvbuf, sizeof(recvbuf),0);printf("%s", recvbuf);memset(recvbuf, 0, sizeof(recvbuf));}/*用戶輸入信息了,開始處理信息并發送*/if(FD_ISSET(0, &rfds)){char sendbuf[BUFFER_SIZE];fgets(sendbuf, sizeof(sendbuf), stdin);send(sock_cli, sendbuf, strlen(sendbuf),0); //發送memset(sendbuf, 0, sizeof(sendbuf));}}}close(sock_cli);return 0; }完美異步聊天服務端和客戶端
以上的多客戶聊天不是很好, 因為只允許兩個客戶端連接, 體驗非常差, 如果支持無限個客戶端聊天的話那該多好啊, 哈哈, 這個也是可以的, 我們只要使用c++的list即可, 它是可以自增的數組(其實算是鏈表), 引用 頭文件即可:
無限個客戶聊天的服務器端代碼
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <sys/shm.h> #include <iostream> #include <thread> #include <list>#define PORT 7000 #define IP "127.0.0.1"int s; struct sockaddr_in servaddr; socklen_t len; std::list<int> li;//用list來存放套接字,沒有限制套接字的容量就可以實現一個server跟若干個client通信void getConn() {while(1){int conn = accept(s, (struct sockaddr*)&servaddr, &len);li.push_back(conn);printf("%d\n", conn);} }void getData() {struct timeval tv;tv.tv_sec = 10;//設置倒計時時間tv.tv_usec = 0;while(1){std::list<int>::iterator it;for(it=li.begin(); it!=li.end(); ++it){ fd_set rfds; FD_ZERO(&rfds);int maxfd = 0;int retval = 0;FD_SET(*it, &rfds);if(maxfd < *it){maxfd = *it;}retval = select(maxfd+1, &rfds, NULL, NULL, &tv);if(retval == -1){printf("select error\n");}else if(retval == 0){//printf("not message\n");}else{char buf[1024];memset(buf, 0 ,sizeof(buf));int len = recv(*it, buf, sizeof(buf), 0);printf("%s", buf);}}sleep(1);} }void sendMess() {while(1){char buf[1024];fgets(buf, sizeof(buf), stdin);//printf("you are send %s", buf);std::list<int>::iterator it;for(it=li.begin(); it!=li.end(); ++it){send(*it, buf, sizeof(buf), 0);}} }int main() {//new sockets = socket(AF_INET, SOCK_STREAM, 0);memset(&servaddr, 0, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(PORT);servaddr.sin_addr.s_addr = inet_addr(IP);if(bind(s, (struct sockaddr* ) &servaddr, sizeof(servaddr))==-1){perror("bind");exit(1);}if(listen(s, 20) == -1){perror("listen");exit(1);}len = sizeof(servaddr);//thread : while ==>> accpetstd::thread t(getConn);t.detach();//detach的話后面的線程不同等前面的進程完成后才能進行,如果這里改為join則前面的線程無法判斷結束,就會//一直等待,導致后面的線程無法進行就無法實現操作//printf("done\n");//thread : input ==>> sendstd::thread t1(sendMess);t1.detach();//thread : recv ==>> showstd::thread t2(getData);t2.detach();while(1)//做一個死循環使得主線程不會提前退出{}return 0; } /*這個跟前面的不一樣的地方是,把獲得連接套接字getConn和發送信息sendMess和接收信息getData放在三個函數中,創建 的三個線程分別對應處理三個函數,就可以使得server能跟若干個client通信*/問:為什么要創建三個線程去處理三個函數,單個線程并不可以嗎,多線程和單線程處理起來有什么不同?
答:首先,這里用到多線程的目的是為了提高處理能力,減少等待時間,多線程可以并發執行,即可以同時對三個函數進行處理,處理起來會快很多。這里也是可以用單線程來處理的,但是單線程每次只能做一件事情,不能同時去獲得連接套接字、發送消息、接收消息,這樣在做其中一件事情的時候其他的兩件事情就要等待,這樣處理時間會比多線程慢很多。多線程可以及時的響應,單線程不能及時響應。
無限個客戶端連接的客戶端代碼
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <sys/shm.h>#define MYPORT 7000 #define BUFFER_SIZE 1024 int main() {int sock_cli;fd_set rfds;struct timeval tv;int retval, maxfd;///定義sockfdsock_cli = socket(AF_INET,SOCK_STREAM, 0);///定義sockaddr_instruct sockaddr_in servaddr;memset(&servaddr, 0, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(MYPORT); ///服務器端口servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); ///服務器ip//連接服務器,成功返回0,錯誤返回-1if (connect(sock_cli, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0){perror("connect");exit(1);}while(1){/*把可讀文件描述符的集合清空*/FD_ZERO(&rfds);/*把標準輸入的文件描述符加入到集合中*/FD_SET(0, &rfds);maxfd = 0;/*把當前連接的文件描述符加入到集合中*/FD_SET(sock_cli, &rfds);/*找出文件描述符集合中最大的文件描述符*/ if(maxfd < sock_cli)maxfd = sock_cli;/*設置超時時間*/tv.tv_sec = 10;tv.tv_usec = 0;/*等待聊天*/retval = select(maxfd+1, &rfds, NULL, NULL, &tv);if(retval == -1){printf("select出錯,客戶端程序退出\n");break;}else if(retval == 0){printf("客戶端沒有任何輸入信息,并且服務器也沒有信息到來,waiting...\n");continue;}else{/*服務器發來了消息*/if(FD_ISSET(sock_cli,&rfds)){char recvbuf[BUFFER_SIZE];int len;len = recv(sock_cli, recvbuf, sizeof(recvbuf),0);printf("%s", recvbuf);memset(recvbuf, 0, sizeof(recvbuf));}/*用戶輸入信息了,開始處理信息并發送*/if(FD_ISSET(0, &rfds)){char sendbuf[BUFFER_SIZE];fgets(sendbuf, sizeof(sendbuf), stdin);send(sock_cli, sendbuf, strlen(sendbuf),0); //發送memset(sendbuf, 0, sizeof(sendbuf));}}}close(sock_cli);return 0; }局域網通過UDP實現服務端和客戶端的通信, UDP的服務端不需要執行listen函數和accept函數.
轉載: https://www.cnblogs.com/wuyepeng/p/9737583.html
總結
以上是生活随笔為你收集整理的Linux C++ socket编程实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: raw socket 编程实例
- 下一篇: linux键盘映射默认,Linux 中的