sendto:参数无效

时间:2014-03-14 20:25:08

标签: c linux sockets sendto

我正在尝试让程序(客户端)使用C中的套接字与另一个(服务器)进行通信,但我经常从服务器收到错误“无效参数”。

在解释发生了什么之后,我会尝试展示与此问题相关的代码片段:

当涉及到客户端时,我认为一切正常:客户端向服务器发送请求,服务器正确接收消息,但是当服务器尝试回复时,我收到“无效参数”错误。

这是服务器主要功能所使用的变量的声明:

int port = DEFAULT_PORT;
int sock;
struct sockaddr_in hostAdress, clientAdress;
socklen_t clientAdressLength;

这里我将套接字绑定到hostAdress:

sock = socket(PF_INET,SOCK_DGRAM,0);
memset(&hostAdress, 0, sizeof(struct sockaddr_in));
memset(&clientAdress, 0, sizeof(struct sockaddr_in));
hostAdress.sin_family = AF_INET;
hostAdress.sin_port = htons(port);
hostAdress.sin_addr.s_addr = INADDR_ANY;
bind(sock, (struct sockaddr*) &hostAdress, sizeof(hostAdress));

在一些代码之后,我以这种方式使用recvfrom进入接收信息的循环:

recvfrom(sock, dataBuffer, sizeof(dataBuffer), 0, (struct sockaddr*)&clientAdress, &clientAdressLength);

当服务器收到请求时,它会识别它并跳转到此功能(此行为已得到确认):

handle_helloRQ(sock, clientAdress, clientAdressLength);

虽然我知道可以通过sizeof(clientAdress)获得“clientAdressLength”,但是上次我这样做时修复了同样的问题。 此函数声明为:

int handle_helloRQ(int sock, struct sockaddr_in server_addr, socklen_t server_addr_length)

在此函数中,主要变量是:

char buffer[512];
size_t bufferSize = sizeof(buffer);
memset(&buffer, 0, sizeof(buffer));
stshort(2, buffer);
strcat(buffer+2, "Hello World");

stshort是一个简单的宏,它在缓冲区的前2个字节中放置一个short int。这可以按预期工作。

完成后,它会尝试执行以下操作:

sendto(sock, buffer, bufferSize, 0, (struct sockaddr*)&server_addr, server_addr_length);

......这就是出问题的时候。 sendto返回-1,并使用perror("sendto");我收到“Invalid Argument”错误。 我尝试了一千种不同的方法来输入参数,但我找不到错误。当涉及到这类问题时,我已经筋疲力尽了其他选择(即,询问我大学的老师并向一些更高级的同事展示代码),似乎没有人能够找到错误。 作为旁注,我确实使用

close(sock);

当服务器收到要关闭的信号时,我可能不得不在它设法达到此功能之前强行关闭它。

对于正在阅读本文的人,谢谢你的时间!

1 个答案:

答案 0 :(得分:3)

请改为尝试:

sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); // <-- add protocol
...    
clientAdressLength = sizeof(clientAdress); // <-- add this
recvfrom(sock, dataBuffer, sizeof(dataBuffer), 0, (struct sockaddr*)&clientAdress, &clientAdressLength);
...
handle_helloRQ(sock, (struct sockaddr*)&clientAdress, clientAdressLength); // <-- pass address by pointer
...
close(sock);

int handle_helloRQ(int sock, struct sockaddr* recip_addr, socklen_t recip_addr_length)
{
    char buffer[512];
    memset(&buffer, 0, sizeof(buffer));
    stshort(2, buffer);
    strcat(buffer+2, "Hello World");

    sendto(sock, buffer, sizeof(buffer), 0, recip_addr, recip_addr_length);
    ...
}