开发者

Ensuring no packet loss between TCP client and server

I am writing a Java TCP client which sends chunks of data to a C server. The client-server worked very well on my development PC. This code upon deployment on a hardware board showed packet loss. I only have the logs with me and I know that the server did not receive all packets. I do not have the hardware to test. Therefore, at the first level, I want to be very sure client code does send all the required data.

Here is my code(the client part in Java). How do I make sure this is done? Is there some resend commands with timings etc?

        Socket mySocket = new Socket("10开发者_开发问答.0.0.2",2800);
        OutputStream os = mySocket.getOutputStream();         

        System.out.println(" Sending 8 byte Header Msg with length of following data to Server");
        os.write(hdr, 0, 8);  
        os.flush();

        System.out.println(" Sending Data ");
        start = 0;
        for(int index=0; index < ((rbuffer.length/chucksize)+1); index++){             
            if(start + chucksize > rbuffer.length) {
                System.arraycopy(rbuffer, start, val, 0, rbuffer.length - start);
            } else {
                System.arraycopy(rbuffer, start, val, 0, chucksize);
            }
            start += chucksize ;

            os.write(val,0,chucksize);  
            os.flush();
        }

Here is the C snippet which receives this data:

while ((bytes_received = recv(connected, rMsg, sizeof(rMsg),0)) > 0){

 if (bytes_received  > 0)      // zero indicates end of transmission */
    {
    /* get length of message (2 bytes) */
    tmpVal = 0;
    tmpVal |= rMsg[idx++];
    tmpVal = tmpVal << 8;
    tmpVal |= rMsg[idx++];
    msg_len = tmpVal;

    len = msg_len;
    //printf("msg_len = %d\n", len);
    printf("length of following message from header message : %d\n", len);
    char echoBuffer[RCVBUFSIZE] ;        
    memset(echoBuffer, 0, RCVBUFSIZE);
    int recvMsgsize = 0;

    plain=(char *)malloc(len+1);
    if (!plain)
    {
     fprintf(stderr, "Memory error!");
    }
    for( i = RCVBUFSIZE; i < (len+RCVBUFSIZE); i=i+RCVBUFSIZE){
     if(i>=len){
         recvMsgSize = recv(connected, echoBuffer, (len - (i-RCVBUFSIZE)), 0);
         memcpy(&plain[k], echoBuffer, recvMsgSize);
         k = k+recvMsgSize;
     }
     else{
         recvMsgSize = recv(connected, echoBuffer, RCVBUFSIZE, 0);
         memcpy(&plain[k], echoBuffer, recvMsgSize);
         k = k+recvMsgSize;
      }
    }
 }//closing if
}//closing while


First of all there is no such thing as packet loss in TCP/IP. This protocol was designed to reliably send a stream of bytes in correct order. So the problem must be with your application or the other side.

I am not really in a mood to analyze this whole arraycopy() madness (C anyone?), but why aren't you just sending the whole rbuffer in one go through BufferedOutputStream?

OutputStream os = new BufferedOutputStream(mySocket.getOutputStream());

and then:

os.write(rbuffer);

Believe me, BufferedOutputStream is doing the exact same thing (collecting bytes into chunks and sending them in one go). Or maybe I am missing something?


I changed the C side program in the following way and it now works:

                    printf("length of following message from header message : %d\n", len);

                    plain=(char *)malloc(len+1);
                    if (!plain)
                    {
                        fprintf(stderr, "Memory error!");

                    }
                    memset(plain, 0, len+1);
                    int remain = len;
                    k= 0;
                    while (remain){
                        int toGet = remain > RCVBUFSIZE ? RCVBUFSIZE : remain;
                        remain -= toGet;
                        int recvd = 0;
                        while(recvd < toGet) {
                            if((recvMsgSize = recv(connected, echoBuffer, toGet-recvd, 0)) < 0){
                                printf("error receiving data\n");
                            }
                            memcpy(&plain[k], echoBuffer, recvMsgSize);
                            k += recvMsgSize;
                            printf("Total data accumulated after recv input %d\n", k);
                            recvd += recvMsgSize;
                        }
                    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜