我编写了一个利用pthreads
和TCP/IP
通信来实现以下目的的C程序:
“ 每个运行该程序的节点都会以给定的频率(秒)生成一些消息。当两个节点连接时,每个节点必须更新另一个节点的消息列表(缓冲区)。整个过程必须连续运行。”] >
我的程序在前10分钟内正常运行。之后,我得到这个错误:
客户端连接错误:连接超时
并且节点停止交换消息,尽管它们一直用自己创建的消息来感觉自己的环形缓冲区(未在下面的代码中显示)。
请注意,此错误发生在第10分钟精确地
。还请注意,如果在发生错误后重新启动一个节点,则通信将重新建立,并且节点将再次继续交换消息。我向您介绍我的代码的简化版本,重点放在似乎重现该问题的行上。 (尽管我尝试使程序保持完整以使问题重现,这就是为什么我包含了#include
和#define
的原因)
?#include <stdio.h> #include <string.h> #include <pthread.h> #include <stdlib.h> #include <unistd.h> #include <time.h> #include <sys/time.h> #include <errno.h> #include <assert.h> //timestamp to string convertion #include <sys/socket.h> #include <sys/types.h> //for server #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h> //for client #define MAX 80 #define MAX_LENGTH 80 #define MAX_MESSAGES 15 #define PORT 2288 #define SA struct sockaddr #define NUM_THREADS 3 #define RECEIVERS 3 char final_message[MAX_LENGTH]; pthread_t tid[NUM_THREADS]; pthread_mutex_t lock; char *buffer[MAX_MESSAGES]; //circular buffer keeps list of node's messages int msg=0; //general buffer index int sent[RECEIVERS]= {0}; //indicates the last message to be sent //oversimplified buffer_fill function //I have taken care of the boundary cases void buffer_fill(const char *minima){ if (msg<MAX_MESSAGES){ buffer[msg] = (char *)malloc(MAX_LENGTH); }else{ msg = MAX_MESSAGES-1; } strcpy(buffer[msg], minima); msg ++; } //function for Server void chat_server(int sockfd) { char buff[MAX_LENGTH]; bzero(buff, MAX_LENGTH); while(recv(sockfd, buff, sizeof(buff),0)>0){ // read messages client has to sent and copy them in buffer pthread_mutex_lock(&lock); buffer_fill(buff); pthread_mutex_unlock(&lock); bzero(buff, MAX_LENGTH); } } void *server(void *threadid) { long tid; tid = (long)threadid; char buff[MAX_LENGTH]; int sockfd, connfd; socklen_t len; struct sockaddr_in servaddr, cli; // socket create and verification sockfd = socket(AF_INET, SOCK_STREAM, 0); //Reuse the port: if client exits then allow them to reconnect setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &(int){ 1 }, sizeof(int)); bzero(&servaddr, sizeof(servaddr)); // assign IP, PORT servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(PORT); // Binding newly created socket to given IP and verification bind(sockfd, (SA*)&servaddr, sizeof(servaddr)); // Now server is ready to listen and verification listen(sockfd, RECEIVERS); len = sizeof(cli); for(;;){ // Accept the data packet from client and verification connfd = accept(sockfd, (SA*)&cli, &len); chat_server(connfd); } // After chatting close the socket close(sockfd); sockfd = -1; pthread_exit(NULL); } void chat_client(int sockfd, int temp_id){ for(int i=sent[temp_id]; i<msg; i++){ send(sockfd, buffer[i], strlen(buffer[i])+1, 0); printf("Just sent: %s\n", buffer[i]); usleep(0.2 * 1000000); //control sending speed } usleep(0.5 * 1000000); } void *client(void *threadid) { long tid; tid = (long)threadid; int temp_id=-1; int sockfd, connfd; struct sockaddr_in servaddr, cli; char address_list [3][11] = {"10.0.XX.YY", "10.0.AA.BB", "10.0.TT.ZZ"}; for(;;){ // socket create and varification sockfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); temp_id++; if(temp_id>RECEIVERS){ temp_id=0; } // assign IP, PORT servaddr.sin_family = AF_INET; //pick an address bettween address_list[0:len] servaddr.sin_addr.s_addr = inet_addr(address_list[temp_id]); servaddr.sin_port = htons(PORT); if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) != 0) { //printf("connection with the server failed...\n"); perror("Client connection error: "); //exit(0); }else{ chat_client(sockfd, temp_id); //printf("connected to the server..\n"); } close(sockfd); sockfd = -1; } pthread_exit(NULL); } int main(int argc, char **argv) { pthread_t threads[NUM_THREADS]; int rc[NUM_THREADS]; long t; for(t=0; t<NUM_THREADS; t++){ //initiallize thread pthread_mutex_init(&lock, NULL); //create each thread according to value of t if(t==0){ rc[t] = pthread_create(&threads[t], NULL, server, (void *)t); }else if(t==1){ rc[t] = pthread_create(&threads[t], NULL, client, (void *)t); } } pthread_join(tid[0], NULL); pthread_join(tid[1], NULL); pthread_mutex_destroy(&lock); /* Last thing that main() should do */ pthread_exit(NULL); return 0; }
我如何处理连接超时错误
我已经阅读了有关将服务器的套接字设置为非阻止模式的信息,但我不知道该如何工作。
我已经编写了一个使用pthread和TCP / IP通信以实现以下目标的C程序:“运行该程序的每个节点都会以给定的频率(秒)生成一些消息。...
除了: