我写了一个简单的C UDP客户端和服务器,客户端将一个字符发送到服务器。在同一台电脑上一切正常。所以我想把一个角色发送到远程电脑。不幸的是,它没有工作:服务器没有收到任何东西,但使用wireshark我可以看到数据包正在到达正确的目的地。
这是代码: (servip包含服务器的地址)
//client
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#define SERV_PORT 50000
int main(){
int id, s;
char buf;
char servip[] = "...";
id = socket(AF_INET,SOCK_DGRAM,0);
buf = 'a';
struct sockaddr_in servaddr;
memset((void *)&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
inet_pton(AF_INET,servip, &servaddr.sin_addr); //controlla se minore di 0
s = sendto(id,&buf,sizeof(char),0,(struct sockaddr *) &servaddr,sizeof(servaddr));
if (s == 0)
fprintf(stderr,"errore in sendto");
return EXIT_SUCCESS;
}
//server
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define SERV_PORT 50000
int main(){
int id, s;
unsigned int len;
char buf;
id = socket(AF_INET,SOCK_DGRAM, 0);
struct sockaddr_in addr;
memset((void *)&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY); /* il server accetta pacchetti su
una qualunque delle sue interfacce di rete */
addr.sin_port = htons(SERV_PORT); /* numero di porta del server */
len = sizeof(addr);
bind(id, (struct sockaddr *) &addr, sizeof(addr));
s = recvfrom(id,&buf,sizeof(char),0,(struct sockaddr *) &addr,&len);
printf("%c\n",buf);
if (s==0)
fprintf(stderr,"errore in recvfrom");
return EXIT_SUCCESS;
}
任何人都可以帮助我吗?我究竟做错了什么?你能否链接我一个实际在远程主机上工作的UDP服务器和客户端的例子? 提前谢谢。
答案 0 :(得分:2)
首先,您应该测试“bind”,“recvfrom”和“sendto”的每个状态,如果发生错误,它们都返回“-1”。双方,客户端和服务器。 您还应该检查变量全局变量errno的状态以了解发生的错误。
检查您的防火墙。如果您没有在同一主机上使用客户端和服务器,请在客户端和服务器上尝试使用wireshark。
添加标头errno以检查errno。
#include <errno.h>
.
.
.
if (sendto(id,&buf,sizeof(char),0,(struct sockaddr *) &servaddr,sizeof(servaddr))== -1) {
int errsv = errno;
printf("sendto() failed\n");
if (errsv == ...) { ... }
}
.
答案 1 :(得分:1)
我怀疑你会想bind
到套接字来设置源地址和端口:
struct sockaddr_in myaddr;
memset((char *)&myaddr, 0, sizeof(myaddr));
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
myaddr.sin_port = htons(0);
if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
perror("bind failed");
exit (1);
}
如果wireshark显示数据包已发送,您是否可以确认它还显示服务器上收到的数据包?这应该有助于消除防火墙和路由问题。