c - linux在c中跨线程连接到相同的sockaddr

标签 c linux sockets pthreads

我试图通过共享传递给 connect()const struct sockaddr_in 来让多个套接字连接到多个线程中的相同地址和端口。但是无法建立连接。

我的代码是这样的:

#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <pthread.h>

void* foo(void* sa) {
  struct sockaddr_in* server_address = (struct sockaddr_in*) sa;
  int sockfd = socket(AF_INET, SOCK_STREAM, 0);
  if (connect(sockfd, (struct sockaddr*)&server_address, sizeof(server_address)) != 0) {
    perror("Cannot connect in foo\n");
    exit(1);
  }
  // do something...
  return NULL;
}

int main(int argc, char* argv[]) {
  const struct sockaddr_in server_address = {
    .sin_addr = inet_addr("127.0.0.1"),
    .sin_port = htons(80),
    .sin_family = AF_INET
  };
  int sockfd = socket(AF_INET, SOCK_STREAM, 0);
  if (connect(sockfd, (struct sockaddr*)&server_address, sizeof(server_address)) != 0) {
    perror("Cannot connect in main\n");
    exit(1);
  } else {
    printf("It works in main\n");
  }
  pthread_t t;
  pthread_create(&t, NULL, foo, (void*)&server_address);
  pthread_join(t, NULL);
}

像这样输出

It works in main
Cannot connect in foo
: Invalid argument

我可以在 main 中写入和读取套接字,但在 foo 中失败。

sockaddr_in 有什么问题?

现在我每次连接时都必须在每个线程中重新创建相同的 sockaddr_in。有什么有效的方法可以避免这些开销?

我在 Ubuntu 16.04 上,编译并运行了 gcc 5.4.1

$ gcc myconnect.c -lpthread && ./a.out

最佳答案

函数 foo 中的

sizeof(server_address)struct sockaddr_in pointer 的大小,而不是 struct sockaddr_in< 的大小 因为它需要。类似(struct sockaddr*)&server_address不是指向struct sockaddr_in的指针而是指向指针:

void* foo(void* sa) {
  struct sockaddr_in* server_address = (struct sockaddr_in*) sa;
  ...
  if (connect(sockfd, (struct sockaddr*)&server_address, sizeof(server_address)) != 0) {

这应该可以代替:

if (connect(sockfd, (struct sockaddr*)server_address, sizeof(*server_address)) != 0) {

关于c - linux在c中跨线程连接到相同的sockaddr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49831208/

相关文章:

c - While 循环在第一个循环后不接收数据

c++ - 从 fread() 失败中恢复的好方法是什么?

C - 将 base64 方法添加到我的文件中

linux - 删除两个句子对齐文件中的重复行,Linux

c++ - 使用 Boost Asio 同步 HTTPS POST

java - 如何使用 Java 服务器将图像发送到 Android 设备

c - 如何解三位数之和,以及如何计算第二个数

linux - 如何在 Linux 中杀死一系列连续的进程?

python - Google App Engine + PyCrypto =/dev/urandom 不可访问

iphone - 在 iPhone 上发送 UDP 数据包在新的 3G 连接上失败,但在其他情况下有效