UDP套接字:服务器发送文件到客户端的地址族不受协议族支持 [英] UDP socket: server sending file to client Address family not supported by protocol family

查看:150
本文介绍了UDP套接字:服务器发送文件到客户端的地址族不受协议族支持的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是在套接字编程初学者,目前正在一个小程序处理使用UDP文件传输。这个程序是用C写的

下面是我的问题:结果
UDP服务器将首先使用recvfrom的()函数从UDP客户端,以便赶上消息开始发送一个文件。我把文件名头,而且它不能经历了,有出现:不受协议系列的作为错误消息支持的地址族()。我检查client_addr的sin_family,它是7.此外,当我试图设置的 client_addr.sin_family = AF_INET 的;服务器工作正常,只是客户端甚至无法收到任何消息。

我也查了一些来源,但它发生就没有那么有帮助,请如果有谁知道为什么,并愿意告诉。鸭preciate你的帮助。

下面是服务器code的一小部分:

  INT socketfd;
/ *我的地址信息* /
结构SOCKADDR_IN SERVER_ADDR;
/ *连接器的地址信息* /
结构SOCKADDR_IN client_addr;
socklen_t的clientLength;
INT的numBytes;
字符缓冲区[BUFLEN]
INT端口编号=的atoi(端口);
time_t的定时器;
炭charfileSize [20];
INT个百分点,计数= 0;
结构TM * tm_info;
CHAR timeBuf [30];
如果((socketfd =插座(AF_INET,SOCK_DGRAM,IPPROTO_UDP))== -1){
  PERROR(服务器套接字()的sockfd错误笑!);
  出口(1);
}其他{
  的printf(服务器套接字()的sockfd是OK ... \\ n);
}server_addr.sin_family = AF_INET;
server_addr.sin_port = htons号(端口);
server_addr.sin_addr.s_addr = INADDR_ANY;
memset的(及(server_addr.sin_zero),0,8);//绑定套接字服务器的IP地址
如果(绑定(socketfd,(结构sockaddr *)及SERVER_ADDR,的sizeof(结构sockaddr))== -1){
  PERROR(服务器套接字绑定到IP错误笑\\ n!);
  出口(1);
}其他{
  的printf(绑定成功与插座服务器的ip ... \\ n);
}
// client_addr.sin_port = htons号(端口);
client_addr.sin_family = AF_INET;// *确保客户端连接* //
INT tempGet;
焦炭tempBuf [BUFLEN]
//如果((tempGet = recvfrom的(socketfd,tempBuf,BUFLEN,0,(结构sockaddr *)及client_addr,&放大器; clientLength))大于0){
tempGet = recvfrom的(socketfd,tempBuf,BUFLEN,0,(结构sockaddr *)及client_addr,&安培; clientLength);
如果(STRCMP(tempBuf发送文件)== 0){
  的printf(可以开始传输文件... \\ n);
}
的printf(仙族数:%d \\ n,client_addr.sin_family);FILE *计划生育=的fopen(文件名,RB);
如果(!FP){
  PERROR(错误打开文件\\ n);
  出口(1);
}其他{
  //成功打开那将要传输的文件
  的printf(打开文件:%s的\\ n,文件名);  //获取文件大小
  INT file_block_size = 0;
  bzero(缓冲,BUFLEN);
  长FILE_SIZE;
  fseek的(FP,0,SEEK_END);
  FILE_SIZE = FTELL(FP);
  //追溯到文件(FP)的开始
  倒带(FP);
  的printf(文件名称:%s \\ n,文件名);
  的printf(文件大小:%ld的KB \\ n,FILE_SIZE / 1024);
  //获取时间
  时间(安培;定时器);
  clientLength = sizeof的(client_addr);  //client_addr.sin_family = AF_INET;
  INT sendFileName;
  //文件名长度
  如果((sendFileName = SENDTO(socketfd,文件名,strlen的(文件名),0,(结构sockaddr *)及client_addr,的sizeof(结构SOCKADDR_IN)))> = 0){
    的printf(文件名发送\\ n);
  }其他{
    //的printf(%d个\\ N,sendFileName);
    PERROR(文件名发送错误。\\ n);
    出口(1);
  }
}


解决方案

的最后一个参数 recvfrom的需要的地址 socklen_t的这需要与sockaddr的参数的大小进行初始化。我没有看到 clientLength 在此之前调用初始化,所以 client_addr 很可能没有被正确时,这个函数返回更新。这将导致 SENDTO 后续调用失败。

如果您初始化 clientLength 之前调用 recvfrom的,将采取照顾的问题。

  clientLength = sizeof的(client_addr);
tempGet = recvfrom的(socketfd,tempBuf,BUFLEN,0,(结构sockaddr *)及client_addr,&安培; clientLength);

I am just a beginner in socket programming and currently working on an small program dealing with file transfer using UDP. This program is written in C.

Here is my problem:
UDP server will first use the recvfrom() function to catch message from UDP client so to start sending a file. I sent the file name first, and it couldn't went through, appearing with: Address family not supported by protocol family as the error message(). I checked the sin_family of client_addr, and it is 7. Furthermore, after I tried to set client_addr.sin_family = AF_INET; the server worked fine, except that the client couldn't even receive any message.

I have checked some sources but it happened to be not so helpful, please if anyone knows why and willing to tell. Appreciate all your help.

Below is a short portion of server code:

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);
  }
}

解决方案

The last argument to recvfrom takes the address of a socklen_t which needs to be initialized with the size of the sockaddr parameter. I don't see clientLength initialized prior to this call, so client_addr is probably not being updated properly when this function returns. This causes the subsequent call to sendto to fail.

If you initialize clientLength before calling recvfrom that will take care of the problem.

clientLength = sizeof(client_addr);
tempGet = recvfrom(socketfd, tempBuf, BUFLEN, 0, (struct sockaddr *)&client_addr, &clientLength);

这篇关于UDP套接字:服务器发送文件到客户端的地址族不受协议族支持的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆