您能告诉我如何解决这个问题的方向和建议吗?这是代码:
#includes...
#define BUF_SIZE 512
#define PORT 1234
#define IP "192.168.0.103" // address of a client
static int val = 1;
int sent=0;
int main() {
struct sockaddr_in client,server;
char tmp[BUF_SIZE];
int n,s,fd;
ssize_t numRead;
int rv,optval=1;
if((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))<0){
printf("Opening datagram socket error",strerror(errno));
return 1;
}else{
printf("Opening datagram socket....OK.\n");
}
if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1){
printf("Setsockopt error: %s", strerror(errno));
return 1;
}
memset((char *) &server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(PORT);
memset((char *) &client, 0, sizeof(client));
client.sin_family = AF_INET;
client.sin_addr.s_addr = inet_addr(IP);
client.sin_port = htons(PORT);
if(bind(s, (struct sockaddr*)&server, sizeof(server))){
printf("Binding datagram socket error %s",strerror(errno));
close(s);
return 1;
}
if((fd = open("udp_text.txt", O_RDONLY , 0777))== -1){
printf("Error while opening txt file %s!\n",strerror(errno));
return 1;
}
while (1) {
if((numRead = read(fd,tmp,512)) == 512){
tmp[numRead]='\0';
rv = sendto(s,tmp,sizeof(tmp),0, (struct sockaddr *) &client, sizeof(struct sockaddr_in));
memset(tmp,0,BUF_SIZE);
}else{
rv = sendto(s,tmp,sizeof(tmp),0, (struct sockaddr *) &client, sizeof(struct sockaddr_in));
printf("EOF !\n");
return 1;
}
}
close(s);
return 0;
}
THX
答案 0 :(得分:0)
由于并非所有数据包都显示在wireshark中,我猜测发送方在操作系统中的网络数据包缓冲区空间不足。 UDP不仅会因传输故障而丢失数据包,而且如果任何路由组件的容量耗尽,并且因为太忙而被迫丢弃数据包。这包括本地互联网协议栈。
首先,检查sendto()中的错误代码。如果要责怪本地操作系统,则可能会有礼貌地报告错误。
更新:sendto()没有错误,那么,没有简单的解决方法。
最后一点注意事项/建议。即使主机之间的直接以太网连接也不能保证数据包始终能够通过。如果您依赖于可靠传输的文件数据,那么您需要从接收器添加某种确认响应以确认数据的成功接收。发送方中的关联逻辑可根据需要重新传输数据。
这是一项相当多的工作,为什么你可能宁愿切换到为你做这一切的TCP套接字。
答案 1 :(得分:0)
如果要通过UDP发送文件,至少要使用为此目的设计的现有协议,例如Trivial FTP(请参阅RFC 1350)。它提供缓冲区大小控制和丢弃数据包的安全性。