c - “已连接” UDP 套接字,双向通信?
问题描述
如何在连接的 UDP 套接字上实现 2 路通信?
我可以从客户端向服务器发送消息,但无法从服务器获取消息。这是我的代码。我认为这个问题一定是在服务器端,但我不知道如何解决这个问题。我故意删除了错误检查,只是为了在 SO 上发布并保持我的帖子简短。我没有收到任何错误。
我可以使用未连接的UDP 套接字运行该程序,但不能使用已连接的套接字。
服务器.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
int main()
{
int sockfd;
struct sockaddr_in me;
char buffer[1024];
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
memset(&me, '\0', sizeof(me));
me.sin_family = AF_INET;
me.sin_port = htons(8080);
me.sin_addr.s_addr = inet_addr("127.0.0.1");
bind(sockfd, (struct sockaddr *)&me, sizeof(me));
recv(sockfd, buffer, 1024, 0);
printf("[+]Data Received: %s\n", buffer);
strcpy(buffer, "Hello Client\n");
send(sockfd, buffer, 1024, 0);
printf("[+]Data Send: %s\n", buffer);
return 0;
}
客户端.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
int main()
{
int sockfd;
struct sockaddr_in other;
char buffer[1024];
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
memset(&other, '\0', sizeof(other));
other.sin_family = AF_INET;
other.sin_port = htons(8080);
other.sin_addr.s_addr = inet_addr("127.0.0.1");
connect(sockfd, (struct sockaddr *)&other, sizeof(other));
strcpy(buffer, "Hello Server\n");
send(sockfd, buffer, 1024, 0);
printf("[+]Data Send: %s\n", buffer);
recv(sockfd, buffer, 1024, 0);
printf("[+]Data Received: %s\n", buffer);
return 0;
}
服务器输出
[+]Data Received: Hello Server
[+]Data Send: Hello Client
客户端的输出
[+]Data Send: Hello Server
// Here it does not receive the message sent by server.
解决方案
On linux, strace
ing the executable, the server send does say this:
sendto(3, "Hello Client\n\0\0\0\310$\220\4J\177\0\0\0\0\0\0\0\0\0\0"...,
1024, 0, NULL, 0) = -1 EDESTADDRREQ (Destination address required)
i.e. the server socket indeed does not know the address it needs to send to. Any UDP socket must make the other end of the socket known by either connect
ing, or providing the destination socket address in sendto
.
connect
on an UDP socket means just setting a default address for send
.
To connect the socket on the "server" side, with an unknown party you should use recvfrom
to find out the socket address of the sending party - then you can connect
using this address or continue using sendto
. With sendto
the same socket can communicate with many different parties concurrently.
The TCP server/client sockets are a different case, because listen/accept on the server side returns a new connected socket that is distinct from the original server socket.
推荐阅读
- scala - 如何连接数据框中前一行的列?
- postgresql - 如何查询表中每个日期的频率
- git - 是否可以使用一个 git repo 并从两个不同的分支运行两个站点?
- angular - 如何在 Angular Nebular 主题中创建响应式 TopNav?
- python - 使用 lambda 函数进行 pandas.DataFrame 布尔索引报告 TypeError
- flutter - 在让可拖动...可拖动之前检查参数的任何方法?
- c# - 如何选择最大日期计数和显示
- python - (使用 pandas)数据库单元不会在功能之外更新。该怎么办?
- regex - PowerShell 从字符串中提取文本
- twilio - Twilio Flex 服务器端事件回调