gpt4 book ai didi

sockets - UDP 套接字没有响应

转载 作者:行者123 更新时间:2023-12-03 12:05:23 25 4
gpt4 key购买 nike

我正在写一个 c udp 套接字的示例。
这是客户端

#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <arpa/inet.h>

int
main(int argc, char *argv[]) {
if (argc < 3) {
fprintf(stderr, "Usage: %s ip port\n", argv[0]);
exit(1);
}

int sock;
char *server_ip;
unsigned short server_port;
struct sockaddr_in cliAddr, serAddr;

if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
fprintf(stderr, "socket failed\n");
exit(1);
}

server_ip = argv[1];
server_port = atoi(argv[2]);

memset(&cliAddr, 0, sizeof(cliAddr));
cliAddr.sin_family = AF_INET;
cliAddr.sin_addr.s_addr = htonl(INADDR_ANY);
cliAddr.sin_port = htons(21152);

if (bind(sock, (struct sockaddr *) &cliAddr, sizeof(struct sockaddr)) < 0) {
fprintf(stderr, "bind failed\n");
exit(1);
}

memset(&serAddr, 0, sizeof(serAddr));
serAddr.sin_family = AF_INET;
serAddr.sin_addr.s_addr = inet_addr(server_ip);
serAddr.sin_port = htons(server_port);

if (sendto(sock, "hello", 5, 0, (struct sockaddr *) (&serAddr), sizeof(serAddr)) == -1) {
fprintf(stderr, "sendto failed\n");
exit(1);
}

printf("send success\n");

int n;
char recvstr[50];
if ((n = recvfrom(sock, &recvstr, 50, 0, NULL, NULL)) < 0) {
fprintf(stderr, "recvfrom failed\n");
exit(1);
}

printf("receive success: %s\n", recvstr);
printf("from %s:%d\n", inet_ntoa(serAddr.sin_addr), ntohs(serAddr.sin_port));

exit(0);
}

这是服务器
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>

int
main(int argc, char *argv[]) {
if (argc < 2) {
fprintf(stderr, "Usage: %s port\n", argv[0]);
exit(1);
}

int sock, n;
struct sockaddr_in servaddr, cliaddr;
char recvstr[50];
socklen_t cliaddrlen;

if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
fprintf(stderr, "socket failed\n");
exit(1);
}

memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(atoi(argv[1]));

if (bind(sock, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
fprintf(stderr, "bind failed\n");
exit(1);
}

cliaddrlen = sizeof(cliaddr);
if ((n = recvfrom(sock, recvstr, 50, 0, (struct sockaddr *) &cliaddr, &cliaddrlen)) < 0) {
fprintf(stderr, "recvfrom failed\n");
exit(1);
}

printf("client ip: %s, client port: %d\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));

if (sendto(sock, "hello from server", 17, 0, (struct sockaddr *) &cliaddr, cliaddrlen) == -1) {
fprintf(stderr, "sendto failed\n");
exit(1);
}

printf("send success\n");

exit(0);
}

当客户端和服务器在本地时,它工作正常。
如“./server 21151”和“./client 127.0.0.1 21151”。
服务器将获得:
client ip: 127.0.0.1, client port: 21152
send success

客户将获得:
send success
receive success: hello from serverB
from 127.0.0.1:21151

但是当我将ip更改为公共(public)ip时,客户端无法得到响应
从服务器。
客户端将在函数 recvfrom 处停止。

有任何想法吗?

最佳答案

让我猜猜 - 你是在 Mac 上运行它并且防火墙是打开的?默认过滤规则将允许发送 UDP 并接收响应(客户端),但不允许在打开的套接字(服务器)上接收未经请求的数据报。

否则您的代码很好,尽管您不一定需要 bind(2)套接字的客户端。内核将为源分配下一个可用的高编号端口。您可以考虑使用 connect(2)如果您计划在给定客户端和服务器之间进行任何扩展对话,则在客户端上。

您还总是希望明确地零终止从网络接收到的字符串。不这样做是无穷无尽的远程攻击的根源。

关于sockets - UDP 套接字没有响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23209415/

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