繁体   English   中英

C:: 线程不一致地打开发送套接字

C :: Threads Inconsistently Open a Sending Socket

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我正在构建一个 C 程序,我正在与gethostbyname()的一个奇怪且不一致的线程和套接字错误搏斗,这是我以前从未见过的。

首先是一些环境方面的东西:我正在开发一个 Ubuntu 盒子,我的代码是用 GCC 编译的:

root@ubuntu:/home/me/socketProject# gcc -v
...
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)
root@ubuntu:/home/me/socketProject#

这里的目标:我已经开发了另一个 C 程序,我希望它有一天会成为网络服务。 服务器工作正常,但我需要对其进行压力测试。 所以我建立了一个客户端程序来用模拟的网络请求轰炸它。 一旦服务器启动并监听 TCP 12345,客户端程序只需要执行以下操作:

  • N 次,启动一个分离的工作线程
    • 每个线程应该打开一个发送套接字,然后通过 TCP 12345 向 127.0.0.1 发送一些数据
    • 发送后,线程应立即终止

这应该是儿戏。 我想使用大量的 N 来查看当我的服务器被重击时会发生什么。

让我带你看一下我的代码,然后描述问题。 程序比较简单。 有一些结构,然后是main() 基本上, main()循环 N = numThreads ,每次都创建一个分离的工作线程。 每个线程都有一个填充的package结构,其信息将在以后使用:

typedef struct{
   int sock;
   struct sockaddr address;
   int addr_len;
} connection_t;

typedef struct{
   char* IP;
   int port, myNum;
} package;


void process(void* pack);                  // code for the thread, see below...


int main( int argc, char ** argv ){
   pthread_t  thread;
   int        numThreads = 10;             // or 100 or 1000 or whatever
   char       svrIP[20] = "127.0.0.1";
   int        portNumber = 12345;

   int i=0;
   for( ; i<numThreads; i++){

      package* pack   = (package*) malloc( sizeof(package) );
      pack->IP        = (char*) malloc( sizeof(char) * 20 );
      strcpy( pack->IP, svrIP );
      pack->port      = portNumber;
      pack->myNum     = i;

      pthread_create(&thread, NULL, process, (void*) pack);
      pthread_detach(thread);

      free( pack->IP );
      free( pack );
   }

   sleep(1);

   printf("END OF PROGRAM\n");
   return 0;
}

无论我为numThreads设置了什么,上面的一切都很好。 现在是线程的代码。 出生时,线程尝试打开一个套接字,然后发送一个文本字符串。 然后线程终止。 请注意gethostbyname()周围的所有fprintf()代码——我稍后会提到它:

void process(void* pack){
   int                  len, sock = -1;
   struct sockaddr_in   address;
   struct hostent *     host;

   char* msg = "Some text string here for the server...";

   printf("THREAD %d STARTED:  %s  --  %d\n", ((package*)pack)->myNum, ((package*)pack)->IP, ((package*)pack)->port );

   // create the socket
   sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
   if (sock <= 0){
      fprintf( stderr, "Thread %d: error: cannot create socket\n", ((package*)pack)->myNum );
      pthread_exit(0);
   }

   // connect to server
   address.sin_family = AF_INET;
   address.sin_port = htons( ((package*)pack)->port );
   host = gethostbyname( ((package*)pack)->IP );
   if (!host){
      fprintf( stderr, "Thread %d: error: unknown host %s  --  Error is:  (%d) \”%s\”\n",
            ((package*)pack)->myNum,
            ((package*)pack)->IP,
            errno, strerror(errno));
      pthread_exit(0);
   }

   memcpy(&address.sin_addr, host->h_addr_list[0], host->h_length);
   if (connect(sock, (struct sockaddr *)&address, sizeof(address))){
      fprintf( stderr, "Thread %d: error: cannot connect to host %s\n", ((package*)pack)->myNum, ((package*)pack)->IP );
      pthread_exit(0);
   }

   printf("Thread %d: Sending message \”%s\”\n", ((package*)pack)->myNum, msg);

   len = strlen(msg);
   write(sock, &len, sizeof(int));
   write(sock, msg, len);

   printf("Thread %d: message sent, exiting...\n", ((package*)pack)->myNum );

   close(sock);

   pthread_exit(0);
}

好的,这就是代码。 那么问题来了:

不管我为numThreads设置了什么值,一些工作线程成功地打开了一个套接字,而另一些则没有。 失败的人在调用gethostbyname()时失败了。 查看以下内容; 我已将numThreads设置为 10,这意味着我应该看到 Threads 0 到 9 启动:

me@ubuntu:/home/me/socketProject# ./runTest
THREAD 2 STARTED:  127.0.0.1  --  24601
THREAD 5 STARTED:  127.0.0.1  --  24601
THREAD 3 STARTED:  127.0.0.1  --  24601
THREAD 3 STARTED:  127.0.0.1  --  24601
THREAD 4 STARTED:  127.0.0.1  --  24601
THREAD 7 STARTED:  127.0.0.1  --  24601
Thread 7: Sending message "Some text string here for the server..."
Thread 7: message sent, exiting...
THREAD 7 STARTED:  127.0.0.1  --  24601
Thread 7: Sending message "Some text string here for the server..."
Thread 7: message sent, exiting...
THREAD 8 STARTED:  127.0.0.1  --  24601
Thread 8: Sending message "Some text string here for the server..."
Thread 8: message sent, exiting...
THREAD 9 STARTED:    --  24601
THREAD 9 STARTED:    --  24601
Thread 9: Sending message "Some text string here for the server..."
Thread 9: message sent, exiting...
Thread 9: error: unknown host   --  Error is:  (0) "Success"
Thread 9: error: unknown host   --  Error is:  (0) "Success"
Thread 9: error: unknown host   --  Error is:  (0) "Success"
Thread 9: error: unknown host   --  Error is:  (0) "Success"
Thread 9: error: unknown host   --  Error is:  (0) "Success"
Thread 9: error: unknown host   --  Error is:  (0) "Success"
END OF PROGRAM
me@ubuntu:/home/me/socketProject#

服务器收到四条测试消息,正如上面的 output 所暗示的那样。

呜呜呜……这里发生了很多奇怪的事情。 那些“ THREAD X STARTED ”消息肯定有一些错误,因为看起来线程 0、1 和 6 从未启动,而线程 3、7 和 9 不知何故启动了两次。 但是numThreads == 10 和 10 个线程启动了,所以我暂时忽略这个问题。

更令人担忧的是,六个线程在调用gethostbyname()时失败了。 我承认:对于这段代码,我从教科书中复制了一个示例,但我不记得我从哪里得到它。 但我想知道if(!host)语句是否有意义。 当我在非线程版本中对此进行 beta 测试时没有问题,但现在……

更奇怪的是 Errno 代码是“成功”。 如果成功...为什么通话失败? 我觉得我错过了一些非常非常明显的东西。

我也很困扰这个问题是不一致的。 有时当我测试这个时,7/10 线程成功发送。 有时是 1/10。 我的平均成功率约为 3/10。 如果我对 C 有所了解,那么不一致的问题通常表明变量已成功创建但未初始化。 这里可能需要初始化什么? host结构? 我不确定。

我已经在谷歌上搜索了大约三个小时,但没有找到任何有用的东西。 任何建议或意见将不胜感激。

1 个回复

问题在这里:

  pthread_create(&thread, NULL, process, (void*) pack);
  pthread_detach(thread);

  free( pack->IP );
  free( pack );

...您为新线程( pack )创建了一个特定的资源,然后在线程完成工作之前立即将其删除! 这些对 free 的调用应该在process结束时执行

1 PHP套接字不一致的结果

我面临的一个问题是我对PHP套接字不太了解。 由于通讯似乎不稳定并且无法确定流超时的设置,因此我得到“不一致”结果。 长话短说:我试图获得一些客户端通过VPN连接到的套接字服务器(我知道,我的服务器目前还不是多线程的,我将需要更多技巧!)以获取最新的配置。今天我关心的是为星号生成多个配置 ...

3 jQuery click()不一致地被调用

我要疯了。 我有一系列的div绑定了单击事件。 他们中的大多数人都按预期工作,但其中一些人什么也没做。 它们之间的代码没有区别(无论是在生成它们的javascript中还是在元素检查器中看到的结果HTML中)。 它们都可以在Safari中工作,但是在Chrome中,我有时会失败。 在下 ...

4 Java:通过套接字与多个本地客户端发送的数据不一致

我已经开发了一种有效的聊天服务器,可以承载任意数量的客户端连接。 除了发送字符串外,该服务器还可以接收和中继2个不同的Java对象。 除了将从客户端接收的数据传播到所有其他客户端之外,服务器本身还可以发送数据。 我只有一台机器可以测试,因此测试变得很困难。 有了一个客户端,一切就可以 ...

5 套接字阻塞接收到不一致的消息

我正在为适用于套接字和1个服务器的聊天客户端系统编写测试。 我创建了3个套接字(每个线程在一个代表客户端的套接字)中选择聊天室(“美国会议室”)并全部发送1条消息,这是我要做的启动服务器,等待所有客户端进入会议室,每个发送一条消息,然后从每个套接字关闭服务器中读取所有消息,但是在读取某些套接字 ...

6 Python 套接字:数据不一致?

这是我与房间进行分散式聊天的代码,如果我两天前刚刚学习了 python 的草率语法,请道歉.. 所以预期的结果是,当与节点建立新连接时,客户端向节点发送一个 !R 命令, 第一次发生这种情况时,它应该创建一个房间(这是一个包含 msg 列表的 dict),然后每当其他人加入该房间时,服务器就会 ...

2021-10-20 06:41:02 0 32   python
7 W3C是否不一致地定义了xs:language数据类型?

根据W3C数据类型规范的3.3.3节 : 语言表示[RFC 3066]定义的自然语言标识符。 language的值空间是所有字符串的集合,这些字符串是定义为[RFC 3066]的有效语言标识符。 语言的词汇空间是符合模式[a-zA-Z] {1,8}(-[a-zA-Z0-9] {1, ...

2018-07-30 14:25:01 0 16   xsd
10 didSelectRowAtIndexPath不一致地返回错误的行索引

我有一个带有行的表格视图,单击该行时,有时它返回的行比我单击的行高一个位置。 相关代码: 我如何解决该问题: 1.用numberOfRows函数检查数组的一致性(正确,数字正确) 2.检查单元格的高度-怀疑上部单元格与下部单元格重叠-并非如此 3.重构cellForR ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM