c - UDP套接字和线程的问题

标签 c multithreading sockets udp

我遇到了 UDP 套接字的问题。

对于这个特定的程序,单个 .c 文件需要既是另一台服务器的客户端(通过 TCP),又是其自身的服务器/客户端(执行两次,在不同的服务器上运行)。它将同时运行两次,因为它需要能够同时进行 TCP 连接(对于一种类型的数据)和 UDP 连接(对于不同类型的数据),所以它需要完成用线或 fork ,但我用的是线。

我遇到的问题是 UDP 套接字没有从彼此接收任何数据报。没有编译错误并且运行良好,但除了一般调试打印语句外没有任何输出。它卡在 recvfrom 命令处。

下面的代码分为两部分(同样,在同一个 .c 文件中)。顶部是服务器部分,下部是客户端部分。这一切都是在一个线程中完成的。我尝试创建套接字然后使用客户端代码调用线程(想法是线程将与父级通信但没关系),但它得到了相同的结果。所以,目前,线程只处理 UDP 连接,父线程处理 TCP。

如果您需要更多解释,请随时询问。这是一项学校作业,所以我不能给太多,但我会尽我所能。

谢谢!

快速编辑:下面所有这些代码所做的只是向服务器发送问候语并返回给客户端。不需要进一步的详细信息。

假设argv->stuff是我传递给线程的结构体,用户在执行时提供服务器、IP地址和端口。

//----- Server portion of code is below

int cli2_sockfd; 
char buffer_cli2[MAXLINE]; 
char *hello2 = "Hello from client 2"; 
struct sockaddr_in cli2_addr, client1_addr; 
int clis_portno = atoi(argv->port);
clis_portno = clis_portno + 1;

// Creating socket file descriptor 
if ( (cli2_sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { 
    perror("socket creation failed"); 
    exit(EXIT_FAILURE); 
} 

memset(&cli2_addr, 0, sizeof(cli2_addr)); 
memset(&client1_addr, 0, sizeof(client1_addr)); 

// Filling server information 
cli2_addr.sin_family = AF_INET; // IPv4 
cli2_addr.sin_addr.s_addr = INADDR_ANY; 
cli2_addr.sin_port = htons(clis_portno); 

// Bind the socket with the server address 
if ( bind(cli2_sockfd, (const struct sockaddr *)&cli2_addr, 
        sizeof(cli2_addr)) < 0 ) 
{ 
    perror("bind failed"); 
    exit(EXIT_FAILURE); 
} 

while(1)
{
    int n2;
    socklen_t len2;
    if((n2 = recvfrom(cli2_sockfd, (char *)buffer_cli2, MAXLINE, 
                0, ( struct sockaddr *) &client1_addr, 
                &len2)) < 0)
    {
        perror("svr recvfrom");
        exit(EXIT_FAILURE);
    }

    buffer_cli2[n2] = '\0'; 
    printf("Client 1: %s\n", buffer_cli2); 

    if(sendto(cli2_sockfd, (const char *)hello2, strlen(hello2), 
        MSG_CONFIRM, (const struct sockaddr *) &client1_addr, 
            len2) < 0)
    {
        perror("svr sendto");
        exit(EXIT_FAILURE);
    }
    printf("Hello message sent.\n"); 
}


//----- The client portion of the code is below


int client1_sockfd; 
char buffer[MAXLINE]; 
char *hello1 = "Hello from client 1"; 
struct sockaddr_in   client2_addr; 
struct hostent *client_2;
clis_portno = atoi(argv->port);
clis_portno = clis_portno + 1;

// Creating socket file descriptor 
if ( (client1_sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { 
    perror("socket creation failed"); 
    exit(EXIT_FAILURE); 
} 

memset(&client2_addr, 0, sizeof(client2_addr)); 

if((client_2 = gethostbyname(argv->name)) == NULL)
{
    perror("cli gethostbyname");
    exit(EXIT_FAILURE);
}

bzero((char *) &client2_addr, sizeof(client2_addr));

// Filling Client 2 information 
client2_addr.sin_family = AF_INET; 
bcopy((char *)client_2->h_addr, (char *)&client2_addr.sin_addr.s_addr, client_2->h_length);
client2_addr.sin_port = htons(clis_portno); 

while(1)
{
    int n1;
    socklen_t len1;

    if( sendto(client1_sockfd, (const char *)hello1, strlen(hello1), 
        0, (const struct sockaddr *) &client2_addr, 
            sizeof(client2_addr)) < 0)
    {
        perror("cli sendto");
        exit(EXIT_FAILURE);
    }

    printf("IN THREAD: Hello1 = %s\n", hello1); 

    if((n1 = recvfrom(client1_sockfd, (char *)buffer, MAXLINE, 
                MSG_WAITALL, (struct sockaddr *) &client2_addr, 
                &len1)) < 0)
    {
        perror("cli recvfrom");
        exit(EXIT_FAILURE);
    }

    buffer[n1] = '\0'; 
    printf("IN THREAD: Client 2 : %s\n", buffer); 
}

最佳答案

您忘记初始化 len2:

socklen_t len2;
if((n2 = recvfrom(cli2_sockfd, (char *)buffer_cli2, MAXLINE, 
            0, ( struct sockaddr *) &client1_addr, 
            &len2)) < 0)

更好:

socklen_t len2 = sizeof(client1_addr);
n2 = recvfrom(cli2_sockfd, (char *)buffer_cli2, MAXLINE, 
        0, ( struct sockaddr *) &client1_addr, 
        &len2));
if (n2 < 0)
{
   ….

不确定这是否是阻止接收数据包的唯一问题。

关于c - UDP套接字和线程的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55961978/

相关文章:

c - 为什么此代码会导致浮点异常 - SIGFPE

c - 在 c 中使用 ntfw 时跳过子目录

java - 尝试让 protected block 正常工作

java - 在 Thread.sleep() 完成之前禁用用户输入

c - C中通过http发送图像

Android ,在一个简单的在线游戏中连接两个用户,比如井字游戏

C 类型转换问题(Float 断言为 Int)

c++ - 你可以通过 fseek 过去的 EOF 创建未定义的数据吗?

objective-c - iOS - 在不卡住 UI 的情况下处理数据

c# - 如何获取套接字中接收到的数据长度?