130-网络编程:端口复用
生活随笔
收集整理的這篇文章主要介紹了
130-网络编程:端口复用
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
4、端口復用
fgets(sendBuf, sizeof(sendBuf), stdin);-默認是阻塞的 #include <stdio.h> #include <arpa/inet.h> #include <stdlib.h> #include <unistd.h> #include <string.h>int main() {// 創建socketint fd = socket(PF_INET, SOCK_STREAM, 0);if(fd == -1) {perror("socket");return -1;}struct sockaddr_in seraddr;inet_pton(AF_INET, "127.0.0.1", &seraddr.sin_addr.s_addr);seraddr.sin_family = AF_INET;seraddr.sin_port = htons(9999);// 連接服務器int ret = connect(fd, (struct sockaddr *)&seraddr, sizeof(seraddr));if(ret == -1){perror("connect");return -1;}while(1) {char sendBuf[1024] = {0};fgets(sendBuf, sizeof(sendBuf), stdin);write(fd, sendBuf, strlen(sendBuf) + 1);// 接收int len = read(fd, sendBuf, sizeof(sendBuf));if(len == -1) {perror("read");return -1;}else if(len > 0) {printf("read buf = %s\n", sendBuf);} else {printf("服務器已經斷開連接...\n");break;}}close(fd);return 0; } #include <stdio.h> #include <ctype.h> #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> #include <string.h>int main(int argc, char *argv[]) {// 創建socketint lfd = socket(PF_INET, SOCK_STREAM, 0);if(lfd == -1) {perror("socket");return -1;}struct sockaddr_in saddr;saddr.sin_family = AF_INET;saddr.sin_addr.s_addr = INADDR_ANY;saddr.sin_port = htons(9999);//int optval = 1;//setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));int optval = 1;setsockopt(lfd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));// 綁定int ret = bind(lfd, (struct sockaddr *)&saddr, sizeof(saddr));if(ret == -1) {perror("bind");return -1;}// 監聽ret = listen(lfd, 8);if(ret == -1) {perror("listen");return -1;}// 接收客戶端連接struct sockaddr_in cliaddr;socklen_t len = sizeof(cliaddr);int cfd = accept(lfd, (struct sockaddr *)&cliaddr, &len);if(cfd == -1) {perror("accpet");return -1;}// 獲取客戶端信息char cliIp[16];inet_ntop(AF_INET, &cliaddr.sin_addr.s_addr, cliIp, sizeof(cliIp));unsigned short cliPort = ntohs(cliaddr.sin_port);// 輸出客戶端的信息printf("client's ip is %s, and port is %d\n", cliIp, cliPort );// 接收客戶端發來的數據char recvBuf[1024] = {0};while(1) {int len = recv(cfd, recvBuf, sizeof(recvBuf), 0);if(len == -1) {perror("recv");return -1;} else if(len == 0) {printf("客戶端已經斷開連接...\n");break;} else if(len > 0) {printf("read buf = %s\n", recvBuf);}// 小寫轉大寫for(int i = 0; i < len; ++i) {recvBuf[i] = toupper(recvBuf[i]);}printf("after buf = %s\n", recvBuf);// 大寫字符串發給客戶端ret = send(cfd, recvBuf, strlen(recvBuf) + 1, 0);if(ret == -1) {perror("send");return -1;}}close(cfd);close(lfd);return 0; }先啟動服務端:
再啟動客戶端:
查看網絡相關信息的命令:netstat參數:-a 所有的socket-p 顯示正在使用socket的程序的名稱-n 直接使用IP地址,而不通過域名服務器查看9999端口:
先啟動服務端;
服務器的ip地址是0,調用了listen函數,處于監聽狀態;
再啟動客戶端:
對于服務器端,有兩個socket,一個是用于監聽的套接字(第1個),還有個是用于通信的套接字(第3個);
客戶端和服務端在通信的過程中, 狀態是不會發生改變的;
現在,主動斷開服務器端:
此時的狀態:
此時是服務端主動斷開,客戶端沒有主動發起關閉,此時服務端處于FIN_WAIT_2狀態
客戶端處于close_wait狀態:
過一會后,只剩下客戶端了,服務端消失了:
重點:
先啟動服務端,再啟動客戶端;
狀態都是正常的:
斷開服務端:
立即運行服務端,不成功
此時服務端的狀態是在FIN_WAIT_2上,客戶端處于CLOSED_WAIT狀態;
處于TIME_WAIT狀態,會有2MSL時間,在這期間,服務器會一直占用9999端口;過了2MSL時間后,進程會真正的結束掉。
端口復用最常用的用途是:
服務器有一個2MLS的時間,端口沒有釋放,不能進行使用
- 防止服務器重啟時之前綁定的端口還未釋放
- 程序突然退出而系統沒有釋放端口
此時,服務端斷開連接后,可以繼續連接,端口復用。
總結
以上是生活随笔為你收集整理的130-网络编程:端口复用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tar zxvf 简单了解
- 下一篇: 线阵相机调帧率_工业相机参数之帧率相关知