Winsock recv()会阻塞,但会在一段时间后退出

时间:2016-03-18 08:37:35

标签: c winsock

此前已经提出过这个问题 Winsock recv() does not block和 在这里C++ Winsock recv not blocking我已经完成了解决方案,但无济于事。 我的方案如下:

我已在VC707 FPGA套件中设置了LWIP服务器,并在我的PC上安装了Windows客户端。客户端将一些数据发送到服务器,然后进入无限循环,等待从服务器recv()数据。

另一方面,服务器从客户端接收数据,调用数据处理操作,然后发回数据。

我在这里面临的问题是,在服务器收到数据之后,整个过程大约需要1分钟,并发布它将发送数据。但是,客户端的recv()函数等待大约30-35秒的数据(由watch监视)然后返回-1和套接字错误10057,在早期的情况下为10060,这意味着连接已经终止。

请让我知道我在哪里以及我做错了什么。

client.c:

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <conio.h>

#pragma comment(lib,"ws2_32.lib")

#define DEFAULT_PORT "9881"
#define DEFAULT_BUFLEN 1460
//#define DEFAULT_BUFLEN 2048
#define DEFAULT_RECV_LEN 2048
#define server_addr "192.168.1.10"

FILE *fid, *fdr;

int main(int argc, char *argv[]) {
    int iResult, recvbuflen = DEFAULT_RECV_LEN, file_pos = 0;
    int bytesRead=0, i=0;
    unsigned char sendbuf[DEFAULT_BUFLEN]={NULL}, recvbuf[DEFAULT_RECV_LEN]={NULL};
    char filename[256];
    WSADATA wsaData;
    struct addrinfo *result = NULL,*ptr = NULL,hints;
    SOCKET ConnectSocket = INVALID_SOCKET;
    int j, iter=0;
    unsigned total_bytes_rx = 0,data_tx_cnt = 0,data_tx_pack_cnt=0;
    unsigned uiNoBytes2Send = 1024;
    unsigned uiNoPackets2Send = 10;
    printf("enter file to transfer: \n");
    scanf("%s", filename);
    printf("Enter number of packets to send (packet size : 1460):");
    scanf("%u",&uiNoPackets2Send);

    fid=fopen(filename,"rb");
    fdr=fopen("D:\\Saravana\\UMA\\DataFiles\\recvfile.bin","wb");
    //fclose(fdr);
    //fdr=fopen("recvfile.txt","w");

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed: %d\n", iResult);
        getch();return 1;
    }

    ZeroMemory( &hints, sizeof(hints) );
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    // Resolve the server address and port
    iResult = getaddrinfo(server_addr, DEFAULT_PORT, &hints, &result);
    if (iResult != 0) {
        printf("getaddrinfo failed: %d\n", iResult);
        WSACleanup();
        getch();return 1;
    }

    ptr=result;

    // Create a SOCKET for connecting to server
    ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, 
        ptr->ai_protocol);
    if (ConnectSocket == INVALID_SOCKET) {
        printf("Error at socket(): %ld\n", WSAGetLastError());
        freeaddrinfo(result);
        WSACleanup();
        getch();return 1;
    }

    // Connect to server.
    iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
    if (iResult == SOCKET_ERROR) {
        closesocket(ConnectSocket);
        ConnectSocket = INVALID_SOCKET;
    }

    freeaddrinfo(result);
    if (ConnectSocket == INVALID_SOCKET) {
        printf("Unable to connect to server!\n");
        WSACleanup();
        getch();return 1;
    }

    //bytesRead=fread(&sendbuf[4],1,DEFAULT_BUFLEN,fid);
    printf("****** Data Sending Initiated ******\n");

    printf("\n ****  Sending control packet  ****");

        sendbuf[0]='c';     sendbuf[1]='t';     sendbuf[2]='r';     sendbuf[3]='l';   //Control string
        sendbuf[4] = 0xC2;  sendbuf[5] = 0x00;  sendbuf[6] = 0x00;  sendbuf[7] = 0x00; //SDRAM Address
        //#Bytes to transfer
        sendbuf[8] = (uiNoPackets2Send&0xFF000000)>>24; 
        sendbuf[9] = (uiNoPackets2Send&0x00FF0000)>>16;
        sendbuf[10] = (uiNoPackets2Send&0x0000FF00)>>8;
        sendbuf[11] = (uiNoPackets2Send&0x000000FF); 

        printf("\n Send buf[11] : %u",sendbuf[11]);

        //iResult = send(ConnectSocket, sendbuf, bytesRead+4, 0);
        iResult = send(ConnectSocket, sendbuf, DEFAULT_BUFLEN, 0);

        if (iResult == SOCKET_ERROR) {
            printf("send failed: %d\n", WSAGetLastError());
            closesocket(ConnectSocket);
            WSACleanup();
            getch();return 1;
        }
        else
        {
            printf("\n Control packet sent successfully");
        }

        printf("\n Starting Data packet transfer ..");

        printf("\n");
    while(data_tx_pack_cnt<uiNoPackets2Send)
    {

        bytesRead=fread(&sendbuf[0],1,DEFAULT_BUFLEN,fid); 
        if(bytesRead<DEFAULT_BUFLEN)
            break;
        //iResult = send(ConnectSocket, sendbuf, bytesRead+4, 0);
        iResult = send(ConnectSocket, sendbuf, DEFAULT_BUFLEN, 0);

        if (iResult == SOCKET_ERROR) {
            printf("send failed: %d\n", WSAGetLastError());
            closesocket(ConnectSocket);
            WSACleanup();
            getch();return 1;
        }
        data_tx_cnt += iResult;
        data_tx_pack_cnt++;
        printf("\r Current Bytes sent : %u \t Current packet cnt : %u ",iResult,data_tx_pack_cnt);
    }
    printf("\n Total bytes transferred: %u\n",data_tx_cnt);


    strcpy(sendbuf,"term");
    iResult = send(ConnectSocket, sendbuf, 1460, 0) ;
    if(iResult <0)
    {
        puts("Send failed\n");
        return 1;
    }else
        printf("\n Control Packet sent to indicate data transfer is complete\n");

    if (iResult == SOCKET_ERROR) {
        printf("shutdown failed: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        getch();return 1;
    }*/




    printf("****** Switching to data receive mode ******\n");
    //Receive until the server closes the connection
    while(1) {

        iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
        printf("iResult: %d\n",iResult);
        if ( iResult > 0 )
        {
            if ( recvbuf[iResult-5]=='m' && recvbuf[iResult-4]=='s' && recvbuf[iResult-3]=='d' && 
                            recvbuf[iResult-2]=='p' && recvbuf[iResult-1]=='d')
            {

                //fwrite(recvbuf,sizeof(char),iResult-5,fdr);
                printf("Connection terminated\n");
                break;
            }   
            fwrite(recvbuf,sizeof(char),iResult,fdr);
            //if(total_bytes_rx%(1024*1024)== 0)
                total_bytes_rx +=iResult;
            printf("\rBytes received: Global %u \t Local : %u", total_bytes_rx,iResult);
            //printf("Bytes received: Local : %u\n",iResult);

            //fclose(fdr);
        }else{
            printf("recv failed: %d\n Closing all Open Sockets\n", WSAGetLastError());
            break;
        }

    } //while( iResult > 0 );

end_pgm:
    fclose(fid);
    fclose(fdr);
    closesocket(ConnectSocket);
    WSACleanup();
    printf("Total Bytes received: %d\n", total_bytes_rx);
    getch();
}

0 个答案:

没有答案