我只是套接字编程的初学者,目前正在开发一个使用UDP处理文件传输的小程序。该程序是用 C 语言编写的。
这是我的问题:
UDP服务器将首先使用recvfrom()函数来捕获来自UDP客户端的消息,以便开始发送文件。我先发送了文件名,但无法通过,并显示:协议(protocol)族不支持地址族作为错误消息()。我检查了client_addr的sin_family,它是7。此外,在我尝试设置client_addr.sin_family = AF_INET之后;服务器工作正常,只是客户端无法接收任何消息。
我检查了一些来源,但碰巧没有那么有帮助,如果有人知道原因并愿意告诉的话,请告诉我。感谢您的所有帮助。
下面是服务器代码的一小部分:
int socketfd;
/* my address information */
struct sockaddr_in server_addr;
/* connector’s address information */
struct sockaddr_in client_addr;
socklen_t clientLength;
int numbytes;
char buffer[BUFLEN];
int portNum = atoi(port);
time_t timer;
char charfileSize[20];
int percent, count = 0;
struct tm *tm_info;
char timeBuf[30];
if((socketfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
perror("Server-socket() sockfd error lol!");
exit(1);
} else {
printf("Server-socket() sockfd is OK...\n");
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(portNum);
server_addr.sin_addr.s_addr = INADDR_ANY;
memset(&(server_addr.sin_zero), 0, 8);
// bind the socket to the server ip address
if(bind(socketfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
perror("server socket bind to IP error lol!\n");
exit(1);
} else {
printf("successfully bind server ip with socket ...\n");
}
// client_addr.sin_port = htons(portNum);
client_addr.sin_family = AF_INET;
//* for ensuring client connection *//
int tempGet;
char tempBuf[BUFLEN];
//if( (tempGet = recvfrom(socketfd, tempBuf, BUFLEN, 0, (struct sockaddr *)&client_addr, &clientLength)) > 0 ) {
tempGet = recvfrom(socketfd, tempBuf, BUFLEN, 0, (struct sockaddr *)&client_addr, &clientLength);
if( strcmp( tempBuf, "send file" ) == 0) {
printf("Can start transferring file...\n");
}
printf("sin family:%d\n", client_addr.sin_family);
FILE *fp = fopen(filename, "rb");
if ( !fp ) {
perror("Error opening the file\n");
exit(1);
} else {
// successfully opened the file that's going to be transferred
printf("file opened: %s\n", filename);
// get file size
int file_block_size = 0;
bzero(buffer, BUFLEN);
long file_size;
fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
// goes back to the beginning of file(fp)
rewind(fp);
printf("file name: %s\n", filename);
printf("file size: %ld kb\n", file_size/1024);
// get time
time(&timer);
clientLength = sizeof(client_addr);
//client_addr.sin_family = AF_INET;
int sendFileName;
// length of file name
if( (sendFileName = sendto(socketfd, filename, strlen(filename), 0, (struct sockaddr *)&client_addr, sizeof(struct sockaddr_in))) >= 0) {
printf("file name sent.\n");
} else {
//printf("%d\n", sendFileName);
perror("file name send error.\n");
exit(1);
}
}
最佳答案
recvfrom
的最后一个参数采用 socklen_t
的地址,该地址需要使用 sockaddr 参数的大小进行初始化。我没有看到 clientLength
在此调用之前初始化,因此当该函数返回时,client_addr
可能没有正确更新。这会导致后续调用 sendto
失败。
如果在调用 recvfrom
之前初始化 clientLength
,问题就会得到解决。
clientLength = sizeof(client_addr);
tempGet = recvfrom(socketfd, tempBuf, BUFLEN, 0, (struct sockaddr *)&client_addr, &clientLength);
关于c - UDP套接字: server sending file to client Address family not supported by protocol family,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35943271/