在進行C語言開發(fā)時,常常需要使用HTTP和JSON來進行數(shù)據(jù)傳輸與處理。然而,在使用C語言進行HTTP請求時,有時候會遇到連接被意外關(guān)閉的情況,這時候我們就需要對代碼進行進一步的優(yōu)化與調(diào)整。
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int main(int argc, char *argv[]) { int sockfd; char *message, response[4096]; struct sockaddr_in servaddr; if (argc != 3) { fprintf(stderr,"usage: %s <URL> <port>\n",argv[0]); exit(1); } if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { fprintf(stderr,"ERROR: Could not create socket. %s\n", strerror(errno)); exit(1); } memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(atoi(argv[2])); if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) { fprintf(stderr,"ERROR: inet_pton error occured\n"); exit(1); } if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { fprintf(stderr,"ERROR: Connect Failed. %s\n", strerror(errno)); exit(1); } message = "GET / HTTP/1.1\r\n\r\n"; if (send(sockfd, message, strlen(message), 0) < 0) { fprintf(stderr,"ERROR: Send Failed. %s\n", strerror(errno)); exit(1); } if (recv(sockfd, response, 4096, 0) < 0) { fprintf(stderr,"ERROR: Receive Failed. %s\n", strerror(errno)); exit(1); } printf("%s\n",response); close(sockfd); return 0; }
以上是一個簡單的HTTP請求的示例代碼,我們可以通過修改代碼來優(yōu)化連接被意外關(guān)閉的問題。
首先,我們需要在發(fā)送請求前設(shè)置SO_KEEPALIVE選項,這樣可以使得連接在一定時間內(nèi)保持活動狀態(tài),防止連接被意外關(guān)閉。
int keepalive = 1; if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)) < 0) { fprintf(stderr, "ERROR: Setsockopt Failed. %s\n", strerror(errno)); exit(1); }
另外,我們可以通過定義一個心跳包來保持連接活動狀態(tài),可以在以下代碼中實現(xiàn):
int heartbeats = 0; char heartbeat[6] = "ping\n"; //定義一個sendheartbeat函數(shù) int sendheartbeat(int sockfd, char *message) { int len, bytes_sent; len = strlen(message); if ((bytes_sent = send(sockfd, message, len, 0)) != len) { fprintf(stderr, "ERROR: Send Failed. %s\n", strerror(errno)); exit(1); } heartbeats++; return bytes_sent; } //主程序中調(diào)用sendheartbeat函數(shù) while (1) { if(sendheartbeat(sockfd, heartbeat) < 0) { fprintf(stderr, "ERROR: Send Failed. %s\n", strerror(errno)); exit(1); } sleep(10); }
以上是兩種解決連接被意外關(guān)閉問題的方法,我們可以根據(jù)具體情況進行代碼優(yōu)化調(diào)整,保證程序的正常運行。