日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

c语言linux TCP长连接 socket收发范例 断开自动重连

發布時間:2023/12/9 linux 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言linux TCP长连接 socket收发范例 断开自动重连 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文鏈接:https://blog.csdn.net/chenhao0568/article/details/103420615

c語言linux TCP長連接 socket收發范例 斷開自動重連
改進1:加入接收超時。可以做別的事,等有接收才響應

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <assert.h> #include <string.h> #include <netinet/in.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <netinet/tcp.h>#include <string.h>#include <arpa/inet.h>#include <sys/socket.h>#include <errno.h>#include <sys/types.h>#include <netdb.h>#include <netinet/in.h>#include <time.h>#include <sys/timeb.h>#include <string.h>#include <stdio.h>#include <fcntl.h>#include <stdlib.h>#include <unistd.h>#include <sys/stat.h>#include <locale.h>// #include "extra/curl/curl.h"//#define IP "192.168.1.127" #define IP "10.0.0.30" #define PORT 3031 long time_last_connected = 0;// //參數解釋 // //fd: 網絡連接描述符 // //start: 首次心跳偵測包發送之間的空閑時間 // //interval: 兩次心跳偵測包之間的間隔時間 // //count: 探測次數,即將幾次探測失敗判定為TCP斷開 // int set_tcp_keepAlive(int fd, int start, int interval, int count) // { // int keepAlive = 1; // //入口參數檢查 ,編程的好習慣。 // if (fd < 0 || start < 0 || interval < 0 || count < 0) // return -1; // //啟用心跳機制,如果您想關閉,keepAlive置零即可 // if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void*) &keepAlive, sizeof(keepAlive)) == -1) // { // perror("setsockopt"); // return -1; // } // //啟用心跳機制開始到首次心跳偵測包發送之間的空閑時間 // if (setsockopt(fd, IPPROTO_TCP , TCP_KEEPIDLE, (void *) &start, sizeof(start)) == -1) // { // perror("setsockopt"); // return -1; // } // //兩次心跳偵測包之間的間隔時間 // if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, (void *) &interval, sizeof(interval)) == -1) // { // perror("setsockopt"); // return -1; // } // //探測次數,即將幾次探測失敗判定為TCP斷開 // if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, (void *) &count, sizeof(count)) == -1) // { // perror("setsockopt"); // return -1; // } // return 0; // } /***read_timeout - 讀超時檢測函數, 不包含讀操作*@fd: 文件描述符*@waitSec: 等待超時秒數, 0表示不檢測超時*成功(未超時)返回0, 失敗返回-1, 超時返回-1 并且 errno = ETIMEDOUT**/ int read_timeout(int fd, long waitSec) {int returnValue = 0;if (waitSec > 0) {fd_set readSet;FD_ZERO(&readSet);FD_SET(fd, &readSet); //添加struct timeval waitTime;waitTime.tv_sec = waitSec;waitTime.tv_usec = 0; //將微秒設置為0(不進行設置),如果設置了,時間會更加精確do{returnValue = select(fd + 1, &readSet, NULL, NULL, &waitTime);}while (returnValue < 0 && errno == EINTR); //等待被(信號)打斷的情況, 重啟selectif (returnValue == 0) { //在waitTime時間段中一個事件也沒到達,超時returnValue = -1; //返回-1errno = ETIMEDOUT;}else if (returnValue == 1) { //在waitTime時間段中有事件產生returnValue = 0; //返回0,表示成功}// 如果(returnValue == -1) 并且 (errno != EINTR), 則直接返回-1(returnValue)}printf("TCP read_timeout:%d\n",returnValue);return returnValue; } // /* activate_nonblock - 設置IO為非阻塞模式 // * fd: 文件描述符 // */ // void activate_nonblock(int fd) // { // int ret; // int flags = fcntl(fd, F_GETFL); // if (flags == -1) // { // perror("fcntl error"); // } // flags |= O_NONBLOCK; // ret = fcntl(fd, F_SETFL, flags); // if (ret == -1) // { // perror("fcntl error"); // } // } // /* deactivate_nonblock - 設置IO為阻塞模式 // * fd: 文件描述符 // */ // void deactivate_nonblock(int fd) // { // int ret; // int flags = fcntl(fd, F_GETFL); // if (flags == -1) // { // perror("fcntl error"); // } // flags &= ~O_NONBLOCK; // ret = fcntl(fd, F_SETFL, flags); // if (ret == -1) // { // perror("fcntl error"); // } // }/* connect_timeout - 帶超時的connect* fd: 套接字* addr: 輸出參數,返回對方地址* wait_seconds: 等待超時秒數,如果為0表示正常模式* 成功(未超時)返回0,失敗返回-1,超時返回-1并且errno = ETIMEDOUT*/ // int connect_timeout(int fd, struct sockaddr_in *addr, unsigned int wait_seconds) // { // int ret; // socklen_t addrlen = sizeof(struct sockaddr_in);// if (wait_seconds > 0) // { // activate_nonblock(fd); //設置為非阻塞模式 // } // printf("\n連接服務器開始\n"); // ret = connect(fd, (struct sockaddr *) addr, addrlen); // printf("\n連接服務器開始[%d,%d]\n", ret,errno); // if (ret < 0 && errno == EINPROGRESS) // { // printf("connect EINPROGRESS\n"); //異步連接 // fd_set connect_fdset; // struct timeval timeout; // FD_ZERO(&connect_fdset); // FD_SET(fd, &connect_fdset);// timeout.tv_sec = wait_seconds; // timeout.tv_usec = 0;// do // { // /* 一旦連接建立,套接字就可寫 */ // ret = select(fd + 1, NULL, &connect_fdset, NULL, &timeout); // } // while (ret < 0 && errno == EINTR);// if (ret == 0) // { // errno = ETIMEDOUT; // return -1; // } // else if (ret < 0) // return -1;// else if (ret == 1) // { // /* ret返回為1,可能有兩種情況,一種是連接建立成功,一種是套接字產生錯誤 // * 此時錯誤信息不會保存至errno變量中(select沒出錯),因此,需要調用 // * getsockopt來獲取 */ // int err; // socklen_t socklen = sizeof(err); // int sockoptret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &socklen); // if (sockoptret == -1) // { // return -1; // } // if (err == 0) // { // ret = 0; // } // else // { // errno = err; // ret = -1; // } // } // } // if (wait_seconds > 0) // { // deactivate_nonblock(fd); // } // return ret; // } int tcp() {printf("\n\n**********TCP開始連接%s:%d\n", IP, PORT);int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0){printf("socket創建失敗:%d\n", sockfd);close(sockfd);sleep(1);return -1;}// printf("socket創建成功:%d\n", sockfd);struct sockaddr_in ser;memset(&ser, 0, sizeof(ser));ser.sin_family = AF_INET;ser.sin_port = htons(PORT);ser.sin_addr.s_addr = inet_addr(IP);int res = connect(sockfd, (struct sockaddr *)&ser, sizeof(ser));if (res < 0){printf("socket連接失敗:%d\n", res);close(sockfd);sleep(1);return -1;}printf("socket連接成功:%d\n", res);while (1){//發送//printf("please input:");fflush(stdin);//清理標準輸入流,把多余的未被保存的數據丟掉。char buff[128] = "1234";//fgets(buff, 128, stdin);//buff[strlen(buff) - 1] = 0;if (strcmp(buff, "end") == 0) //end正常退出{close(sockfd);printf("end正常退出socket\n");return 0;}int sendret = send(sockfd, buff, strlen(buff), 0);if (sendret < 0){printf("socket發送失敗:%d (0服務端斷開,-1網絡故障)\n", sendret);close(sockfd);return -1;}printf("socket發送成功:%d,內容:%s\n", sendret, buff);//接收char recvbuff[1024] = {0};printf("socket接收等待中\n");fflush(stdout);//清空輸出緩沖區,并把緩沖區內容輸出。int ret = read_timeout(sockfd, 10);if(ret==0){int recvret = recv(sockfd, recvbuff, 1023, 0);if (recvret <= 0){printf("socket接收失敗:%d (0服務端斷開,-1網絡故障)\n", recvret);close(sockfd);return -1;}printf("socket接收成功:%d,內容:%s\n", recvret, recvbuff);}} } int main() {while (1){tcp();} }

阻塞

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <assert.h> #include <string.h> #include <netinet/in.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #define IP "192.168.1.127" #define PORT 3031int tcp() {printf("\n\n**********TCP開始連接%s:%d\n", IP, PORT);int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0){printf("socket創建失敗:%d\n", sockfd);close(sockfd);sleep(1);return -1;}// printf("socket創建成功:%d\n", sockfd);struct sockaddr_in ser;memset(&ser, 0, sizeof(ser));ser.sin_family = AF_INET;ser.sin_port = htons(PORT);ser.sin_addr.s_addr = inet_addr(IP);int res = connect(sockfd, (struct sockaddr *)&ser, sizeof(ser));if (res < 0){printf("socket連接失敗:%d\n", res);close(sockfd);sleep(1);return -1;}printf("socket連接成功:%d\n", res);while (1){//發送//printf("please input:");fflush(stdout);char buff[128] = "1234";//fgets(buff, 128, stdin);//buff[strlen(buff) - 1] = 0;if (strcmp(buff, "end") == 0) //end正常退出{close(sockfd);printf("end正常退出socket\n");return 0;}int sendret = send(sockfd, buff, strlen(buff), 0);if (sendret < 0){printf("socket發送失敗:%d (0服務端斷開,-1網絡故障)\n", sendret);close(sockfd);return -1;}printf("socket發送成功:%d,內容:%s\n", sendret, buff);//接收char recvbuff[128] = {0};printf("socket接收等待中\n");int recvret = recv(sockfd, recvbuff, 127, 0);if (recvret <= 0){printf("socket接收失敗:%d (0服務端斷開,-1網絡故障)\n", recvret);close(sockfd);return -1;}printf("socket接收成功:%d,內容:%s\n", recvret, recvbuff);} } int main() {while (1){tcp();} }

總結

以上是生活随笔為你收集整理的c语言linux TCP长连接 socket收发范例 断开自动重连的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。