0

我有以下代码:

该文件是principal.c它具有函数 main 和其他方法。

在 main() 中:

connectAll(&NUM_THREADS);
printf("TOTAL clients that to connect %d\n",NUM_THREADS);

pthread_t thread[NUM_THREADS];
pthread_attr_t attr;

/* Initialize and set thread detached attribute */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
paramThread params[NUM_THREADS];

  for(t=0;t<NUM_THREADS;t++)
  {

    printf("What's IP [%s] to connected now? %d\n",regIPConnected[t].ip,regIPConnected[t].idSocket);

    params[t].idSocket=regIPConnected[t].idSocket;
    params[t].idThread=t;

    rc = pthread_create(&(thread[t]), &attr,conectaThread, &(params[t]));
    if (rc) 
    {
      printf("ERROR; return code from pthread_create() is %d\n", rc);
    } 
  }//END FOR

  /* Free attribute and wait for the other threads */
  pthread_attr_destroy(&attr);

  for(t=0; t<NUM_THREADS; t++) 
  {
    rc = pthread_join(thread[t], &status);
    if (rc<0) {
      printf("ERROR; return code from pthread_join() is %d\n", rc);
    }
    printf("Main: completed join with thread %ld having a status of %ld\n",t,(long)status);
  }//END FOR

  printf("Main: program completed. Exiting.\n");
  pthread_exit(NULL);
}

void *conectaThread (void *arg){

  paramThread* params = (paramThread*) &arg; 

  int idSocket=params->idSocket;
  long tid=params->idThread;

  printf("Thread %ld starting...\n",tid);
  printf ("ID SOCKET THREAD %d\n",idSocket);
  while (1) /* Run forever */
  {

    int state=readSocket(idSocket,"status\n");

...
}

paramThread 的结构是:

typedef struct
{
  int idSocket;
  long idThread;
  void (*pf)(int, long);
} paramThread; 

还有另一个文件,叫做 socket.c

int openSocketInet (char *servIP,unsigned short servPort)
{
  int optval,statusSocket=0;
  socklen_t optlen = sizeof(optval);

  /* Create the socket, using TCP */

  socketClient = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  printf("OK/NOK socket %d",socketClient);
  if (socketClient<0)
  {
    switch (errno) 
    {

      /*differents cases of errno*/
      default:  
    perror("socket()");
    statusSocket= -1;
    }//END SWITCH
  }//END IF


    /* Check the status for the keepalive option */
  if(getsockopt(socketClient, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0 && statusSocket==0) {
    statusSocket=checkGET_SETSockOpt(socketClient,1);
    printf("Error getsockopt() is %d\n",statusSocket);
  }//END IF

  printf("SO_KEEPALIVE is %s\n", (optval ? "ON" : "OFF"));

  int fl = fcntl(socketClient, F_GETFL);
  fcntl(socketClient, F_SETFL, fl | O_NONBLOCK);

  /* Set the option active */
  optval = 1; //-->TRUE
  optlen = sizeof(optval);

  if(setsockopt(socketClient, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0 && statusSocket==0) {
    statusSocket=checkGET_SETSockOpt(socketClient,0);
    printf("Error setsockopt() is %d\n",statusSocket);
  }//END IF

  printf("SO_KEEPALIVE set on socket\n");

  /* Check the status again */
  if(getsockopt(socketClient, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0 && statusSocket==0) {
    statusSocket=checkGET_SETSockOpt(socketClient,1);
    printf("Error getsockopt() is %d\n",statusSocket);
  }//END IF

  printf("SO_KEEPALIVE is %s\n", (optval ? "ON" : "OFF"));


  if (connect(socketClient, (struct sockaddr *)&addressServer, sizeof(addressServer)) < 0 && statusSocket==0)
  {
    switch (errno) 
    {
      /*diffents cases of errno to connect()*/
      default:  
    perror("connect()");
    statusSocket= -1;
    }//END SWITCH
   }//END IF

  /* Construct the server address structure */
  bzero(&addressServer, sizeof(addressServer)); /* Hay que poner todo a ceros */

  addressServer.sin_family = AF_INET;           /* Internet address family */
  addressServer.sin_port = htons(servPort); /* puerto en formato de red */

  /* dirección IP en formato de red */
  int errInetAton=inet_aton(servIP, &addressServer.sin_addr);
  if (errInetAton<0 && statusSocket==0) 
  { 
    printf("Fail the conversion of IP\n",servIP);
    perror("inet_aton() Motive");
    statusSocket= -1;
  }//END IF


  printf("The IP %s to connect with sock %d\n",servIP,socketClient);

  //To return identify a socket or  fail
  if (statusSocket<0)
    return statusSocket;
  else
    return socketClient;

}

当我运行结果是:

socket(): Success --> to sock 3
SO_KEEPALIVE 关闭
SO_KEEPALIVE 在套接字上设置
SO_KEEPALIVE 开启
连接 sock 3 的 IP xxxx
socket(): Illegal seek --> to sock 4
SO_KEEPALIVE 关闭
SO_KEEPALIVE 在套接字上设置
SO_KEEPALIVE 开启
与 sock 4 连接的 IP yyyy

我希望我可以连接到具有相同套接字的不同 ip


谢谢,问题是另一个:

What's IP [x.x.x.x] to connected now? 3
What's IP [y.y.y.y] to connected now? 4
What's IP [z.z.z.z] to connected now? 5


Out for
Thread 5 starting...
ID SOCKET THREAD 5
Method READ! Send to socket id [5] and data is '[status]'
STATUS THREAD 0
Thread 5 starting...
ID SOCKET THREAD 5
Method READ! Send to socket id [5] and data is '[status]'
Thread 5 starting...
ID SOCKET THREAD 5
Method READ! Send to socket id [5] and data is '[status]'
STATUS THREAD 0
Info: (-3.35 dB)
Method WRITE! Send to socket id [5] and data is '[outlevel 0:50
]'
El conector está marcado como no bloqueante y la operación solicitada lo bloquearía.
Method WRITE! Error send() is 0
Level modify of Vol 50%
Info: (-24.13 dB)
Level modify of Vol 50%
Info: (-52.60 dB)
Method WRITE! Send to socket id [5] and data is '[outlevel 0:50
]'
El conector está marcado como no bloqueante y la operación solicitada lo bloquearía.
Method WRITE! Error send() is 0
Level modify of Vol 50%
Method READ! Send to socket id [5] and data is '[status]'
hi0!
send(): No route to host
Method READ! Error send() is -1
STATUS THREAD -1
Method READ! Send to socket id [5] and data is '[status]'
#

但是socket号不正确应该是3或者4,下一个代码:

在主()

...
for(t=0;t<NUM_THREADS;t++)
  {

    printf("What's IP [%s] to connected now? %d\n",regIPConnected[t].ip,regIPConnected[t].idSocket);

idSocket=regIPConnected[t].idSocket;

    rc = pthread_create(&(thread[t]), &attr,conectaThread,&idSocket);
    if (rc) 
    {
      printf("ERROR; return code from pthread_create() is %d\n", rc);
    } 
  }//END FOR

  printf("Out for\n\n!");

  /* Free attribute and wait for the other threads */
  pthread_attr_destroy(&attr);

  for(t=0; t<NUM_THREADS; t++) 
  {
    rc = pthread_join(thread[t], &status);
    if (rc<0) {
      printf("ERROR; return code from pthread_join() is %d\n", rc);
    }
    printf("Main: completed join with thread %ld having a status of %ld\n",t,(long)status);
  }//END FOR

  printf("Main: program completed. Exiting.\n");
  pthread_exit(NULL);

}

其他代码相同。为什么不获取第一个套接字“3”并获取完成套接字 5?为什么要完成线程?

谢谢

4

2 回答 2

1

尝试注释掉这一行

printf("OK/NOK socket %d",socketClient);

看看你能不能走得更远。

有关详细信息,请参阅我对 OP 的评论。

于 2012-04-27T12:32:26.513 回答
0

我没有看到您在套接字初始化函数的任何地方声明 socketClient 。如果它是全局的,它应该由互斥锁或其他一些序列化访问它的机制来保护。

一般来说,

socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

在正常情况下不应该失败。您已经超出了系统 fd/socket 配额,或者更有可能是缺少对套接字的正确访问同步。

此外,如前所述,代码太多,上下文太少。

于 2012-04-27T20:45:43.503 回答