sách gpt4 ai đã đi

Máy khách (chương trình python) không nhận được phản hồi trả về từ máy chủ (chương trình c)?

In lại 作者:太空宇宙 更新时间:2023-11-04 03:13:14 30 4
mua khóa gpt4 Nike

我有一个在服务器端工作的 UDP 套接字应用程序。为了测试服务器端,我编写了一个简单的 python 客户端程序,它发送消息“hello world how are you”。服务器随后应接收消息,将其转换为大写并发送回客户端。问题就在这里:我可以在调试时观察到服务器正在接收消息、应用转换、发回响应并最终等待另一条消息。然而,python 客户端没有收到消息,而是无休止地等待服务器的响应。

我通过网络发现(一个选项)为了让客户端接收到它需要绑定(bind)到服务器的响应,这与我在教科书(Linux 编程接口(interface))中看到的背道而驰。尽管如此,我尝试将客户端绑定(bind)到服务器,但 python 程序无法在绑定(bind)线上连接(不知道我是否正确)。 Python 版本为 2.7.5。客户端程序在 RedHat 上运行,服务器在 Angstrom 的目标模块上运行(它是为 32 位处理器交叉编译的)。

这是客户端的代码:

import socket
nhập khẩu hệ điều hành

UDP_IP = "192.168.10.4"
UDP_PORT = 50005

#dir_path = os.path.dirname(os.path.realpath(__file__))

MESSAGE = "hello world how are you"

print "UDP target IP: ", UDP_IP
print "UDP target port: ", UDP_PORT
print "message: ", MESSAGE

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#sock.bind((UDP_IP, UDP_PORT))
print "Sending message..."
sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))
print "Message sent!"
print "Waiting for response..."
data = sock.recv(1024)

print "Received", repr(data)

这是服务器的代码:

void server_side(void)
{
printf("Server start up.\n");

struct sockaddr_in svaddr;
struct sockaddr_in claddr;
int sfd;
int j;
ssize_t numBytes;
socklen_t len;
char buf[BUF_SIZE];
char claddrStr[INET_ADDRSTRLEN];

//int output = open("test_output.txt", O_WRONLY|O_CREAT, 0664);

printf("Creating new UDP socket...\n");

sfd = socket(AF_INET, SOCK_DGRAM, 0); /* Create Server Socket*/
if (sfd == -1)
{
errExit("socket");
}

printf("Socket has been created!\n");

memset(&svaddr, 0, sizeof(struct sockaddr_in));

svaddr.sin_family = AF_INET;
svaddr.sin_addr.s_addr = htonl(INADDR_ANY);
svaddr.sin_port = htons(PORT_NUM);

printf("Binding in process...\n");

if (bind(sfd, (struct sockaddr *) &svaddr, sizeof(struct sockaddr_in))
== -1)
{
errExit("bind");
}

printf("Binded!\n");

/* Receive messages, convert to upper case, and return to client.*/

for(;;)
{
len = sizeof(struct sockaddr_in);
numBytes = recvfrom(sfd, buf, BUF_SIZE, 0,
(struct sockaddr *) &claddr, &len);
if (numBytes == -1)
{
errExit("recvfrom");
}
if (inet_ntop(AF_INET, &claddr.sin_addr, claddrStr,
INET_ADDRSTRLEN) == NULL)
{
printf("Couldn't convert client address to string.\n");
}
khác
{
printf("Server received %ld bytes from (%s, %u).\n", (long)
numBytes,
claddrStr, ntohs(claddr.sin_port));
}

claddr.sin_port = htons(PORT_NUM);

for (j = 0; j< numBytes; j++)
{
buf[j] = toupper((unsigned char) buf[j]);
}

if (sendto(sfd, buf, numBytes, 0, (struct sockaddr *) &claddr, len)
!= numBytes)
{
fatal("sendto");
}
}
}

同样的问题是我没有收到响应并在客户端打印回消息。我应该收到所有大写字母的相同消息。我觉得我错过了一个小细节。感谢您的帮助!

1 Câu trả lời

快速而肮脏:

从您的 C 代码中删除这一行:

claddr.sin_port = htons(PORT_NUM);

现在为什么:

当您在 python 脚本中发送消息时,您的操作系统将填充 UDP packet使用您指定的目标 IP 地址和端口,您在源 IP 字段中使用的机器的 IP 地址,最后是操作系统“随机”分配的源端口。请注意,这与目标端口不是同一个端口,即使是这样,您怎么知道哪个程序将收到源消息?(两者都会听到来自同一端口的消息)幸运的是,这不是可能。

现在,当您的 C 代码收到此数据包时,它将知道是谁发送了消息,并且您可以通过 recvfrom 填充的 sockaddr 结构访问此信息。如果你想发回一些信息,你必须发送一个目标端口(服务器看到的)等于客户端看到的源端口的数据包,这又不是你正在监听的相同端口服务器。通过执行 claddr.sin_port = htons(PORT_NUM),您可以设置用服务器端口覆盖包含客户端源端口的字段,当您尝试发送此数据包时,可能会发生两件事:

  • 如果客户端从同一台计算机运行,目标 IP 和源 IP 将相同,您刚刚设置了目标端口成为服务器正在监听的端口,因此您将拥有一个消息循环。
  • 如果在不同的计算机上运行,数据包将由客户端计算机收到,但可能不会有任何程序在该端口上等待消息,因此它被丢弃。

一个半生不熟的比喻:你收到一个 friend 的来信,但是给他回信的时候,你把他家的门牌号换成了你家的门牌号……没有多大意义。唯一不同的是,你这位 friend 的 Action 比较大,每个字母的编号可能不同,但这并不重要。

理论上,如果要接收回数据就必须绑定(bind),此时绑定(bind)相当于监听那个端口。这个答案阐明了为什么在这种情况下没有必要:https://stackoverflow.com/a/14243544/6253527

如果您使用的是 Linux,您可以使用 sudo ss -antup | 查看操作系统为 UDP 套接字分配的端口。 grep python

关于python - 客户端(python 程序)没有收到服务器(c 程序)返回的响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54311678/

30 4 0
太空宇宙
Hồ sơ cá nhân

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá Didi Taxi miễn phí
Mã giảm giá Didi Taxi
Giấy chứng nhận ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com