【发布时间】:2016-01-07 21:59:00
【问题描述】:
我正在尝试以非常简单/基本的方式在 C 中实现 UDP 套接字。我的程序旨在在终端之间发送/接收文件,每个终端上运行一个程序。我的客户端代码中的 sendto() 函数有问题。这是我的代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include <errno.h>
#define BUFFER_SIZE 512
int main(int argc, char *argv[])
{
struct sockaddr_in client;
int sockfd, bytes, errno, slen = sizeof(client);
char buffer[BUFFER_SIZE];
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd == -1)
{
perror("Socket creation failed.");
return 0;
}
client.sin_addr.s_addr = INADDR_ANY;
client.sin_family = AF_INET;
client.sin_port = htons( 0 );
if( bind(sockfd, (struct sockaddr *)&client, sizeof(client)) == -1)
{
perror("Bind call failed.");
return 0;
}
while(1)
{
printf("Enter message : ");
fgets(buffer, BUFFER_SIZE, stdin);
printf("Message: %s\n", buffer);
bytes = sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr *)&client, sizeof(client));
printf("Bytes: %d\n", bytes);
if(bytes == -1)
{
printf("Error number: %d", errno);
perror("Send failed.");
return 0;
}
memset(buffer,'\0', BUFFER_SIZE);
if( recvfrom(sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&client, &slen) == -1)
{
perror("Recieve failed.");
return 0;
}
puts(buffer);
}
close(sockfd);
return 0;
}
无论我在缓冲区中输入什么,我总是会从 sendto() 中得到错误号 22 的无效参数。我已经尝试了所有遇到的解决方案或调整,但似乎没有任何效果。
【问题讨论】:
-
您正在尝试发送到端口 0。这是无效的。
-
您可以绑定到端口 0,这会导致自动选择端口。但是您不能发送到端口 0。您可以在绑定后使用
getsockname找出选择了哪个端口。 -
当您调用
bind()时,您正在设置本地端口。端口 0 意味着操作系统应该找到一个未使用的端口并绑定它。 -
无关:在调用
printf()之后再调用perror()是没有意义的,因为printf()可以改变errno。 -
您需要两种不同的
sockaddr_in结构,一种用于绑定客户端地址/端口,另一种用于指定目标地址/端口。