send()和sendto()在文件传输程序中阻塞

时间:2013-07-15 13:46:22

标签: c linux sockets tcp udp

似乎当我使用send()函数(在TCP文件传输程序中)时,就像这样

while((count = recv(socketConnection, buff, 100000, 0))>0)
myfile.write(buff,count);

函数recv()只是等待整个数据进入并退出循环,当它不再接收任何数据但是在UDP程序的类似程序中

while((n = recvfrom(sockfd,mesg,1024,0,(struct sockaddr *)&cliaddr,&len))>0)
myfile.write(mesg,n);

recvfrom()函数只是阻塞并且由于某种原因不会退出循环,据我所知,recv()和recvfrom()都是阻塞的?然后为什么差异。它是否与功能或仅与TCP,UDP的性质有关(我猜这不是一个原因)??

P.S。请帮助我理解这些人,我是套接字编程和网络的新手。 编辑:TCP和UDP的完整服务器程序 UDP服务器(使用recvfrom())

 int i=0;
   int sockfd,n;
   struct sockaddr_in servaddr,cliaddr;
   socklen_t len;
   char mesg[1024];
   sockfd=socket(AF_INET,SOCK_DGRAM,0);
   bzero(&servaddr,sizeof(servaddr));
   servaddr.sin_family = AF_INET;
   servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
   servaddr.sin_port=htons(32000);
   bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
   ofstream myfile;
  // fcntl(sockfd,F_SETFL,O_NONBLOCK);
   myfile.open("2gb",ios::out);

    while((n = recvfrom(sockfd,mesg,1024,0,(struct sockaddr *)&cliaddr,&len))>0)
    myfile.write(mesg,n);

TCP(recv())服务器程序

    struct sockaddr_in socketInfo;
   char sysHost[MAXHOSTNAME+1];  // Hostname of this computer we are running on
   struct hostent *hPtr;
   int socketHandle;
   int portNumber = 8070;
   //queue<char*> my_queue;
   bzero(&socketInfo, sizeof(sockaddr_in));  // Clear structure memory
   gethostname(sysHost, MAXHOSTNAME);  // Get the name of this computer we are running on
   if((hPtr = gethostbyname(sysHost)) == NULL)
   {
      cerr << "System hostname misconfigured." << endl;
      exit(EXIT_FAILURE);
   }
   if((socketHandle = socket(AF_INET, SOCK_STREAM, 0)) < 0)
   {
      close(socketHandle);
      exit(EXIT_FAILURE);
   }
  // std::cout<<"hi starting server";
   socklen_t optlen;
   int rcvbuff=262144;
  optlen = sizeof(rcvbuff);
   socketInfo.sin_family = AF_INET;
   socketInfo.sin_addr.s_addr = htonl(INADDR_ANY); 
   socketInfo.sin_port = htons(portNumber);      // Set port number
   if( bind(socketHandle, (struct sockaddr *) &socketInfo, sizeof(socketInfo)) < 0)
   {
      close(socketHandle);
      perror("bind");
      exit(EXIT_FAILURE);
   }
   listen(socketHandle, 1);
   int socketConnection;
   if( (socketConnection = accept(socketHandle, NULL, NULL)) < 0)
   {
      exit(EXIT_FAILURE);
   }
   close(socketHandle);
time_start(boost::posix_time::microsec_clock::local_time());
   int rc = 0;  // Actual number of bytes read
   int count=0;
   char *buff;
   int a=100000;
   buff=new char[a];


   ofstream myfile;
   myfile.open("345kb.doc",ios::out|ios::app);
   if(myfile.is_open())
   {
    long i=0;
   while((count = recv(socketConnection, buff, 100000, 0))>0)
   {


    myfile.write(buff,count);

    }}

2 个答案:

答案 0 :(得分:3)

  

函数recv()等待直到整个数据出现并在不再接收任何数据时退出循环

当发送方关闭连接时,TCP连接上的

recv()返回0,这是循环终止的条件。

  

对于UDP程序,recvfrom()函数只是阻塞而不会因某种原因退出循环,

因为UDP是无连接协议,因此对于封闭的UDP连接,recv()没有特殊的返回码。除非有人发给你一个0长的数据报。

答案 1 :(得分:1)

recv()将结束循环,因为在另一侧套接字已关闭,因此recv()将返回0(套接字正常关闭),而recvfrom没有该信号,它不知道关闭,因为它是一个未连接的套接字。它一直呆在那里,直到收到数据包或超时,用UDP你需要一种方法来告诉通信结束(完成)。