Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
不要说客户端是如何断开连接的。它只是关上插座吗?它会关机吗?我在套接字上看不到任何close(2),那么为什么您知道是谁正在关闭连接(或者调用shutdown(2)以指示连接中不会出现更多数据)_C_Multithreading_Sockets_Select_Disconnected - Fatal编程技术网

不要说客户端是如何断开连接的。它只是关上插座吗?它会关机吗?我在套接字上看不到任何close(2),那么为什么您知道是谁正在关闭连接(或者调用shutdown(2)以指示连接中不会出现更多数据)

不要说客户端是如何断开连接的。它只是关上插座吗?它会关机吗?我在套接字上看不到任何close(2),那么为什么您知道是谁正在关闭连接(或者调用shutdown(2)以指示连接中不会出现更多数据),c,multithreading,sockets,select,disconnected,C,Multithreading,Sockets,Select,Disconnected,通常,一个连接会阻塞,直到您收到一些数据。。。接收0数据意味着没有数据到达,或者在select(2)调用选择了一个不显示更多数据的套接字描述符后,您关闭了套接字。但是这必须在某个地方关闭,并且您既不显示close(2)也不显示shutdown(2)。您也没有描述在套接字上检测到的内容。如果您从选择(2)唤醒,您将进入文件描述符,读取的结果不是0读取返回的值是什么?您是否知道-1是此类可能的值之一,这意味着您有一个读入错误?是否检查select返回的值?(超时时,我的记忆告诉我select(0)返

通常,一个连接会阻塞,直到您收到一些数据。。。接收0数据意味着没有数据到达,或者在
select(2)
调用选择了一个不显示更多数据的套接字描述符后,您关闭了套接字。但是这必须在某个地方关闭,并且您既不显示
close(2)
也不显示
shutdown(2)
。您也没有描述在套接字上检测到的内容。如果您从
选择(2)
唤醒,您将进入文件描述符,读取的结果不是
0
读取返回的值是什么?您是否知道
-1
是此类可能的值之一,这意味着您有一个读入错误?是否检查select返回的值?(超时时,我的记忆告诉我
select(0)
返回0,那么您是否检查超时?)

请下次提供一个完整且可验证的示例。如果没有大量的贡献,您发布的代码将无法运行,因此问题只能在您这边重现。检查

#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
#include <arpa/inet.h>
#include <fcntl.h> // for open
#include <unistd.h> // for close
#include <pthread.h>
#include <limits.h>
#include <errno.h>
#include <time.h>
#include <sys/wait.h>

#define MAXCLIENTS 1000
#define FRAMESIZE 40

struct Client
{
  int socket;
  char state;
};
struct Client clients[2];

struct ThreadArgs
{
  int srcClientIdx;
  int dstClientIdx;
};

int portNumber=8090;

void * SocketThread(void *args)
{
   printf("New thread created.\n");
   struct ThreadArgs *threadArgs = (struct ThreadArgs*)args;
   int sidx = threadArgs->srcClientIdx;
   int didx = threadArgs->dstClientIdx;
   int srcSocket = clients[sidx].socket;
   int dstSocket = clients[didx].socket;

   fd_set readfds;
   struct timeval timeout;

   while(1)
   {
      FD_ZERO(&readfds);
      FD_SET(srcSocket, &readfds);
      FD_SET(dstSocket, &readfds);

      printf("Waiting for activities in thread.\n");

      timeout.tv_sec = 60;
      timeout.tv_usec = 0;
      int activity = select(MAXCLIENTS+1, &readfds , NULL , NULL , &timeout);
      if ((activity < 0) && (errno!=EINTR))
         printf("Activity error.\n");
      else if(activity == 0)
         printf("Activity timeout.\n");

      if (FD_ISSET(srcSocket, &readfds))
      {
         unsigned char buffer[FRAMESIZE];
         int bytesCnt = read(srcSocket, buffer, sizeof(buffer));
         if(bytesCnt == 0)
         {
           printf("Client%d disconnected.\n",sidx);
           clients[sidx].state = 0;
           clients[sidx].socket = -1;
           pthread_exit(NULL);
         }
         else
           printf("Client%d activity.\n",sidx);
      }

      if (FD_ISSET(dstSocket, &readfds))
      {
         unsigned char buffer[FRAMESIZE];
         int bytesCnt = read(dstSocket, buffer, sizeof(buffer));
         if(bytesCnt == 0)
         {
           printf("Client%d disconnected.\n",didx);
           clients[didx].state = 0;
           close(clients[didx].socket);
           clients[didx].socket = -1;
           pthread_exit(NULL);
         }
         else
           printf("Client%d activity.\n",didx);
      }

   }
 }

 int ConfigureTCPIPconnection(int socket,struct sockaddr_in *serverAddr)
 {
   // Address family = Internet
   serverAddr->sin_family = AF_INET;
   //Set port number, using htons function to use proper byte order
   serverAddr->sin_port = htons(portNumber);
   //Incoming addresses
   serverAddr->sin_addr.s_addr = INADDR_ANY;

   //Set all bits of the padding field to 0
   memset(serverAddr->sin_zero, '\0', sizeof serverAddr->sin_zero);

   //Bind the address struct to the socket
   if(bind(socket, (struct sockaddr *)serverAddr, sizeof(struct sockaddr)) < 0)
   {
     printf("Binding failed. %s\n",strerror(errno));
     return 1;
   }

   printf("Bind sucessfull.\n");
   return 0;
 }

int CheckSocketActivity(fd_set *readfds)
{
   int activity = select( MAXCLIENTS + 1 , readfds , NULL , NULL , NULL);
   if ((activity < 0) && (errno!=EINTR))
      return 1;
   return 0;
}

int main(int argc, char *argv[])
{
  fd_set readfds;
  int serverSocket,newSocket;
  pthread_t td; //thread descriptor
  struct sockaddr_in serverAddr, newAddr={0};
  socklen_t addr_size;

  clients[0].state = 0;
  clients[0].socket = -1;
  clients[1].state = 0;
  clients[1].socket = -1;

  if((serverSocket = socket(PF_INET, SOCK_STREAM, 0)) == 0)
  {
    printf("Server socket creation failed.\n");
    exit(1);
  }

  if(ConfigureTCPIPconnection(serverSocket,&serverAddr))
  {
    printf("Binding failed.\n");
    exit(2);
  }

  if(listen(serverSocket,MAXCLIENTS))
  {
    printf("Listen error.\n");
    exit(3);
  }

  printf("Listening...\n");

  while(1)
  {
    FD_ZERO(&readfds); //clear fd set
    FD_SET(serverSocket, &readfds); //add server socket to fd set
    if(clients[0].state == 1)
      FD_SET(clients[0].socket, &readfds); //add active clients to fd set
    if(clients[1].state == 1)
      FD_SET(clients[1].socket, &readfds);

    printf("Waiting for activities.\n");

    if(!CheckSocketActivity(&readfds))
    {
      if(FD_ISSET(serverSocket, &readfds))
      {
        if((newSocket = accept(serverSocket, (struct sockaddr *)&newAddr, (socklen_t*)&addr_size))<0) //create new socket
          printf("New socket error. %s\n",strerror(errno));
        else
        {
          printf("New socket connected.\n");
          if(clients[0].state == 0)
          {
            printf("Client0 added.\n");
            clients[0].state = 1;
            clients[0].socket = newSocket;
          }
          else if(clients[1].state == 0)
          {
            printf("Client1 added.\n");
            clients[1].state = 1;
            clients[1].socket = newSocket;
          }
        }
      }
        else
        {
           for(int i=0;i<2;i++)
           {
              int srcSock = clients[i].socket;
              if (FD_ISSET(srcSock, &readfds))
              {
                 unsigned char buffer[FRAMESIZE];
                 int bytesCnt = read(srcSock, buffer, sizeof(buffer));
                 if(bytesCnt == 0)
                 {
                   printf("Client%d disconnected.\n",i);
                   clients[i].state = 0;
                   close(clients[i].socket);
                   clients[i].socket = -1;
                 }
                 else
                 {
                   if(clients[0].state == 1 && clients[1].state == 1)
                   {
                      int srcIndex,dstIndex;
                      //some other stuff
                      clients[0].state = 2;
                      clients[1].state = 2;
                      if(i == 0)
                      {
                        srcIndex = 0;
                        dstIndex = 1;
                      }
                      else
                      {
                        srcIndex = 1;
                        dstIndex = 0;
                      }
                      printf("Creating new thread.\n");
                      struct ThreadArgs threadArgs = {srcIndex,dstIndex};
                      if(pthread_create(&td, NULL, SocketThread, &threadArgs) != 0)
                         printf("Failed to create thread.\n");
                      if (pthread_detach(td))
                         printf("Thread detach error.\n");
                    }
                    else
                      printf("Two clients required for creating thread.\n");
                 }
              }
           }
        }
     }
  }
}
void FD_CLR(int fd, fd_set *set);
int  FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set); 
  if (FD_ISSET(dstSocket, &readfds))
   {
      unsigned char buffer[FRAMESIZE];
      bytesCnt = read(srcSock, buffer, sizeof(buffer));
      if(bytesCnt == 0)
         **//this is not detected**
      else
        //any other activities are detected
   }