gpt4 book ai didi

c++ - echo 服务器没有响应 udp

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

我正在尝试实现一个回显客户端。使用 sendto() 的客户端正在传输消息,服务器正在接收并显示它。但是服务器没有发送消息(回显)。这是服务器和客户端的代码。谁能帮我这个?

服务器:

char msg[100]="";
int conn_sock,n;
struct sockaddr_in server_addr,client_addr;
conn_sock=socket(AF_INET,SOCK_DGRAM,0);

server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(1234);
server_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
err=bind(conn_sock, (struct sockaddr *)&server_addr,sizeof(server_addr));

n=recvfrom(conn_sock,msg,sizeof(msg),0,(struct sockaddr *)&client_addr,(socklen_t *)&client_addr);
n=sendto(conn_sock,msg,sizeof(msg),0,(struct sockaddr *)&client_addr,sizeof(client_addr));

recvfrom中n的值是字节数。但在 n 的 sendto() 值是 -1

客户:

char msg[100];
int conn_sock,n,err;
struct sockaddr_in server_addr;
conn_sock=socket(AF_INET,SOCK_DGRAM,0);

server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(1234);
server_addr.sin_addr.s_addr=inet_addr("127.0.0.1");

cin>>msg;
n=sendto(conn_sock,msg,strlen(msg),0,(struct sockaddr *)&server_addr,sizeof(server_addr));
n=recvfrom(conn_sock, msg, 15, 0, (struct sockaddr*) &server_addr,(socklen_t *)&server_addr);

recvfrom() 没有从服务器接收任何数据。

最佳答案

这两行都是错误的:

// In the server
n=recvfrom(conn_sock,msg,sizeof(msg),0,(struct sockaddr *)&client_addr,(socklen_t *)&client_addr);

// In the client
n=recvfrom(conn_sock, msg, 15, 0, (struct sockaddr*) &server_addr,(socklen_t *)&server_addr);

recvfrom() 的最后两个参数应该指向两个独立 变量。其中一个接收另一个对等点的网络地址,另一个接收该网络地址的长度。您将相同的指针值传递给两者意味着地址长度正在覆盖地址数据的前几个字节,破坏它并导致错误。

这是服务器应该如何工作,将长度接收到一个单独的变量中:

struct sockaddr_storage client_addr;
socklen_t client_addr_len = sizeof(client_addr); // This is an in+out parameter
n=recvfrom(..., (struct sockaddr *)&client_addr, &client_addr_len);
n=sendto(..., (struct sockaddr *)&client_addr, client_addr_len);

请注意,我使用了 sockaddr_storage 而不是 sockaddr_insockaddr_storage 保证足够大以容纳支持的地址系列的任何有效套接字地址类型,因此此代码将与 IPv6 向前兼容。

同样,客户端的工作方式如下:

n=sendto(..., &server_addr, sizeof(server_addr));
do
{
struct sockaddr_storage peer_addr;
socklen_t peer_addr_len = sizeof(peer_addr);
n=recvfrom(..., (struct sockaddr *)&peer_addr, &peer_addr_len);
} while (!areSockAddrsEqual((struct sockaddr *)&server_addr, (struct sockaddr *)&peer_addr));

...

bool areSockAddrsEqual(struct sockaddr *addr1, struct sockaddr *addr2)
{
if (addr1->sa_family != addr2->sa_family)
return false;

switch (addr1->sa_family)
{
case AF_INET:
struct sockaddr_in *addr1_in = (struct sockaddr_in *)addr1;
struct sockaddr_in *addr2_in = (struct sockaddr_in *)addr2;
return (addr1_in->sin_port == addr2_in->sin_port &&
addr1_in->sin_addr.s_addr == addr2_in->sin_addr.s_addr);
...
// Other address families such as AF_INET6 left as an exercise
}
}

这里我们再次确保传递一个单独的 socklen_t 指针来接收地址长度,然后我还添加了一个循环以确保我们收到的实际数据包是我们期望的数据包预期的服务器。如果我们反而收到了一个不同的数据包(例如,由于另一个对等点恰好在错误的时间向我们发送了一个数据包),我们将忽略它。

检查两个套接字地址是否相等有点棘手,因为它取决于地址系列,并且同时支持 IPv4 和 IPv6 很棘手。

关于c++ - echo 服务器没有响应 udp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20200664/

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