我正在开发一个涉及通过UDP向服务器发送各种请求的项目。但是,我似乎完全错误地设置了套接字,因为服务器没有响应我的任何请求。我们提供了一个服务器二进制文件来测试,下面的代码没有响应。我是否正确设置了UDP套接字?如果是这样,我是否以某种方式使用sendto错误?我已经确认我发送了正确的位数。
该计划的输入是:./client [URL] [port] [username]
,我总是使用./client localhost 8080 user
进行测试。这是我发送的结构和代码。
struct request_login {
int req_type; /* = REQ_LOGIN */
char req_username[32];
} packed;
代码:
struct sockaddr_in sa;
int sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sockfd == -1){
printf("Could not create socket.");
exit(EXIT_FAILURE);
}
// Prepare the socket address
memset(&sa, 0, sizeof sa);
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr(argv[1]);
// Convert to network order
sa.sin_port = htonl(atoi(argv[2]));
// Assemble and send login request
struct request_login * reqlogin = (struct request_login *) malloc(sizeof(struct request_login));
reqlogin->req_type = REQ_LOGIN;
strcpy(reqlogin->req_username, argv[3]);
int res = sendto(sockfd, reqlogin, sizeof (struct request_login), 0, (struct sockaddr*)&sa, sizeof sa);
free(reqlogin)
答案 0 :(得分:3)
咦?
此:
sa.sin_addr.s_addr = inet_addr(argv[1]);
如果你说argv[1]
通常为"localhost"
,那么肯定不会做正确的事情。您需要查找主机名,以便获得IP地址。如果输入是虚线IP地址而不是主机名,则只能使用inet_addr()
。
答案 1 :(得分:2)
重新阅读你的代码几次后,我想我知道错误的原因可能是:
sa.sin_port = htonl(atoi(argv[2]));
端口号是short
,因此您应该使用htons
。它非常小,容易错过。
答案 2 :(得分:1)
试试这个:
struct addrinfo hint;
memset(&chk,0,sizeof(chk));
hint.ai_family = AF_INET;
hint.ai_socktype = SOCK_DGRAM;
hint.ai_protocol = IPPROTO_UDP;
struct addrinfo* servAddr = NULL;
int ret = getaddrinfo(argv[1],atoi(argv[2]),&hint,&servAddr);
if (-1 == ret)
{
perror("getaddrinfo failed");
exit(EXIT_FAILURE);
}
int sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sockfd == -1){
printf("Could not create socket.");
exit(EXIT_FAILURE);
}
// Assemble and send login request
struct request_login reqlogin;
reqlogin.req_type = REQ_LOGIN;
strcpy(reqlogin.req_username, argv[3]);
int res = sendto(sockfd, &reqlogin, sizeof (struct request_login), 0, servAddr->ai_addr, servAddr->ai_addrlen);