gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 04:12:08 25 4
gpt4 key购买 nike

我遇到了 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com