2012-10-24 24 views
1

我正在处理一个涉及通过UDP向服务器发送各种请求的项目。但是,我似乎设置完全错误的套接字,因为服务器不响应我的任何请求。我们提供了一个服务器二进制文件来测试,而且下面的代码没有响应。我能正确设置UDP套接字吗?如果是这样,我以某种方式使用Sendto错误?我已经确认我发送了正确的位数。C中的UDP套接字 - 设置错误?

程序的输入是:./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) 
+1

什么的返回值'sendto'?那么'request_login'结构怎么样? –

+0

关于'sendto'的返回值,如果它是负值,则输出['errno'](http://linux.die.net/man/3/errno)的值,或者使用['strerror']( http://linux.die.net/man/3/strerror)获取可打印的错误代码字符串。 –

+0

感谢您的回复。 sendto返回36,这是结构的正确位数。我编辑了上面的帖子来显示结构。 – theeggman85

回答

3

咦?

此:

sa.sin_addr.s_addr = inet_addr(argv[1]); 

如果肯定不会做正确的事,就像你说的,argv[1]通常"localhost"。您需要查看主机名称,以便获得IP地址。如果输入是虚线IP地址,而不是主机名,则只能使用inet_addr()

看看getaddrinfo()

+2

使用'getaddrinfo()'可能是比贬低'gethostbyname()'更好的选择。 – alk

+0

@alk谢谢,编辑!显然,自从我进行套接字编程已经太久了。 :) – unwind

+0

谢谢,这个伎俩! – theeggman85

2

重新阅读你的代码几次之后,我想我知道什么是错误的一个原因可能是:

sa.sin_port = htonl(atoi(argv[2])); 

的端口号是short所以你应该使用htons代替。这是非常小,很容易错过。

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); 
+1

非常感谢,这就做到了! – theeggman85