“连接超时”在程序运行的第10分钟内

问题描述 投票:-1回答:1

我编写了一个利用pthreadsTCP/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程序:“运行该程序的每个节点都会以给定的频率(秒)生成一些消息。...

c sockets tcp pthreads connect
1个回答
0
投票

除了:

© www.soinside.com 2019 - 2024. All rights reserved.