C中的UDP套接字 - 设置错误?

时间:2012-10-24 00:44:46

标签: c sockets udp

我正在开发一个涉及通过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)

3 个答案:

答案 0 :(得分:3)

咦?

此:

sa.sin_addr.s_addr = inet_addr(argv[1]);
如果你说argv[1]通常为"localhost",那么肯定不会做正确的事情。您需要查找主机名,以便获得IP地址。如果输入是虚线IP地址而不是主机名,则只能使用inet_addr()

查看getaddrinfo()

答案 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);