通过tcp for t中的tcp stream socket发送文件

时间:2013-12-06 06:13:04

标签: c sockets

我很难弄清楚如何在接收器端退出循环。我有一个tcp流套接字连接,我正在从文件中读取并将其放入缓冲区。接收器端只是一直循环写入相同的信息。我确定这是因为我没有递减nRecv因此它永远不会命中if(nRecv == 0)语句,但我无法弄清楚如何递减它。我正在为发送者和接收者发布while循环,希望有人可以指出我正确的方向。

发送方

    /* prepare file to send */
pf = fopen("input.txt", "rb");

if(pf == NULL)
{
    printf("The file you want to send was not found");
    return(1);
}
else
{
    while (!feof(pf))
    {
        nRead = fread(bufferin, sizeof(char), 256, pf);
        if (nRead <= 0)
            printf("ERROR reading file");
        while (nRead > 0)
        {
            nSent = send(filesender_socket, bufferin, nRead, 0);
            if (nSent < 0)
            {

                    printf("ERROR sending from socket = %d\n", WSAGetLastError());
                    break;

            }
            if (nSent == 0)
                printf("DISCONNECTED writing to socket");
            //pBuf += nSent;
            //nRead -= nSent;
        }
    }
} //end of if statement


    // Close all open sockets
#ifdef WIN
  //retcode = closesocket(jsender_socket);
  retcode = closesocket(filesender_socket);
 if (retcode < 0)
{
 printf("*** ERROR - closesocket() failed \n");
exit(-1);

}       #ENDIF

RECEIVER

    //create a new socket for file transfer
  filesocket = socket(AF_INET, SOCK_STREAM, 0);
  if (filesocket < 0)
  {
    printf("*** ERROR - socket() failed \n");
    exit(-1);
  }

  // >>> Step #2 <<<
  // Fill-in my socket's address information
  receiver_addr.sin_family = AF_INET;                 // Address family to use
  receiver_addr.sin_port = htons(PORT_FILE);           // Port number to use
  receiver_addr.sin_addr.s_addr = htonl(INADDR_ANY);  // Listen on any IP address
  filebindcode = bind(filesocket, (struct sockaddr *)&receiver_addr,sizeof(receiver_addr));
  if (filebindcode < 0)
  {
    printf("*** ERROR - file socket bind() failed \n");
    exit(-1);
  }

    printf("receiver accepting connections\n");

    //2 DEBUG LINES
    printf("received a connection from: %s port %d\n",
    inet_ntoa(sender_addr.sin_addr), ntohs(sender_addr.sin_port));

 if (newsockfd = listen(filesocket, 2) < 0) {
    printf("newsock in listen %d\n", newsockfd);
     perror("listen failed");
     exit(1);
 }
 //listen(filesocket, 2);
 //while(1)   //while loop for to accept files
 //{
 printf("\nwaiting for accept() to complete \n");
  newsockfd = accept(filesocket, (struct sockaddr *) &sender_addr, &addr_len);
  printf("newsock return %d", newsockfd);
    if (newsockfd < 0)
          {
        printf("*** ERROR - accepting() failed \n");
        exit(-1);
      }
    // start receiving file


    fp = fopen("output.txt", "wb");
    if (fp == NULL) 
    {
        printf("File not found!\n");
        return NULL;
    }
    else 
    {
        printf("created file output.txt\n");
    }   

    //receive file 
    while(1)
    {
         nRecv = recv(newsockfd, bufferin, 256, 0);
        if (nRecv < 0)
        {

                printf("ERROR reading from socket = %d\n", WSAGetLastError());
                break;
        }

        if (nRecv == 0)
            break;

        while (nRecv > 0)
        {
             printf("%s", bufferin); // debug
             nWritten = fwrite(bufferin, sizeof(char), nRecv, fp);
            if (nWritten <= 0)
                printf("ERROR writing to file");

            //nRecv -= nWritten;
        }
    }

    printf("File Transfer complete\n\n");     //} //end of while

2 个答案:

答案 0 :(得分:2)

recv()的返回值如下:

  • >0 - 收到的字节数
  • 0 - 没有数据(仅限异步套接字)或其他套接字已完全关闭
  • <0 - 发生错误。

在发件人代码中,您永远不会关闭套接字,因此您的接收方会等待更多数据。

答案 1 :(得分:0)

不确定为什么,但现在我已经注释掉了两行,因为他们现在没有工作......

取消注释以下行

                pBuf += nSent;
            nRead -= nSent;

这些在reciver方面

                nRecv -= nWritten;

它就像一个魅力。

感谢您的帮助。