【问题标题】:Implementing threads with sockets in C在 C 中使用套接字实现线程
【发布时间】:2017-07-09 19:27:07
【问题描述】:

所以我正在尝试用线程实现一个基本的客户端-服务器计算器。我能够使用套接字实现客户端服务器之间的通信,但是当我尝试向代码中添加线程时我不知所措。 这是我第一次使用这个论坛,所以如果我提出一个愚蠢的问题,请抱歉,但我已经搜索了一些答案,但我找不到任何有帮助的东西:( 我现在可以上传我的整个代码位,我认为这就足够了:

在 main 中创建一个线程:

  while(cliente_socket_fd  = accept(socket_fd,(struct sockaddr*)&name_cliente,(socklen_t*)&cliente_name_len))
  {
      pthread_t thread;
      new_sock = malloc(1);
      *new_sock = cliente_socket_fd;
      if(i <= nThreads) // nThreads is the maximum of threads permitted
      {
          if(pthread_create(&thread, NULL, connectionSocket, (void*)new_sock) < 0)
          {
              perror("Error");
              return 1;
          }    
          i++;
      }    
     }

从创建线程接收信息的函数:

 void *connectionSocket(void *sockR)
    {
        int sock = *(int*)sockR;
        int x;
        char buffer[1024];
        do{
           x = strlen(buffer) + 1;
           read(sock,buffer, x);

           readSocket(sock, buffer);
           }while(1 || strcmp(buffer,"end") != 0);

        close(sock);
        return 0;
    }

服务器读取套接字函数:

int readSocket(int sock, const char* buffer)
{
   //char buffer[1024];
   //char message[1024] ;
   int ssize;

   ssize = strlen(buffer);
   if(ssize == 0)
      return 0;
   char* message = (char*) malloc(ssize);


   //memset(buffer, 0, sizeof buffer);
   memset(message, 0, sizeof message);

   strcat(message, buffer);
...
   writeSocket(sock, message);
...

写入套接字的函数:

void writeSocket(int sock, const char* mensagem)
{
   int ssize = strlen(message) + 1;

   write(sock, &ssize, sizeof(ssize));
   write(sock, message, ssize);
}

再次抱歉,如果我是菜鸟或要求太多,但非常感谢任何帮助。谢谢。

【问题讨论】:

  • 这里的实际问题是什么?
  • 一件事:'while(cliente_socket_fd = accept());'为什么那句话是真的?
  • 哦.. 和'new_sock = malloc(1);' - 不够大。
  • 'readSocket()' 不读取套接字。
  • 您需要使用调试器检查所有代码。您有太多严重的错误和太多缺失/误导性的代码/数据,我们无能为力。

标签: c multithreading sockets


【解决方案1】:

在函数中:connectionSocket()

这一行

x = strlen(buffer) + 1;

是垃圾,因为strlen() 在找到 NUL 字节时停止。

但是,buffer 尚未设置为已知条件,因此缓冲区中可能有也可能没有 NUL 字节。 IE。未定义的行为。


accept()函数在发生错误时返回-1,但是发布的代码会盲目地继续进入循环体

建议将该行写成类似于:

while( 1 )
{
    cliente_socket_fd  = accept(socket_fd,(struct sockaddr*)&name_cliente, (socklen_t*)&cliente_name_len) );
    if( -1 == cliente_socket_fd )
    {
        perror( "accept failed" );
        break;  // exit loop
    }

    // implied else, accept successful

然后,为了能够访问这些线程,稍后,这一行:

if(pthread_create(&thread, NULL, connectionSocket, (void*)new_sock) < 0)

应该设置一个“唯一的”“线程”而不是唯一的“线程”建议:

pthread_t thread[ nThreads ] = {0};

if(pthread_create(&thread[i], NULL, connectionSocket, (void*)new_sock) < 0)

那么,套接字(实际上)是一个整数,取决于底层硬件架构,它是 4 或 8 个字节所以这一行:

new_sock = malloc(1);  

没有分配足够的字节,应该是:

new_sock = malloc( sizeof( int ) );
if( !new_sock )
{ // then, malloc failed
    perror( "malloc failed" );
    break;  // exit loop
}

// implied else, malloc successful

*new_sock = cliente_socket_fd;

这一行:

}while(1 || strcmp(buffer,"end") != 0);

永远不会退出循环。建议:

}while( strcmp(buffer,"end") != 0 );

这一行:

read(sock,buffer, x);

将尝试读取一些随机字节数,因为 'x' 中的值无效。建议;

read(sock,buffer, sizeof( buffer ));

以上是发布代码中最明显的问题。如果您发布了一个可以运行并且仍然显示问题的干净编译的简短示例,我可以为您提供更多帮助。

【讨论】:

  • 谢谢你,我会尝试处理你的建议,看看我是否能解决问题或找到更具体的问题。
猜你喜欢
  • 1970-01-01
  • 2018-10-16
  • 2020-02-21
  • 2017-09-22
  • 1970-01-01
  • 1970-01-01
  • 2011-04-12
  • 2013-08-24
  • 2020-10-25
相关资源
最近更新 更多