2011-09-15 65 views
3

我在写一个将TCP数据块发送到C服务器的Java TCP客户端。客户端服务器在我的开发PC上运行得非常好。该代码在硬件板上部署后显示丢包。我只有我的日志,我知道服务器没有收到所有的数据包。 我没有硬件来测试。因此,在第一级,我想确保客户端代码确实发送了所有需要的数据。确保TCP客户端和服务器之间没有数据包丢失

这是我的代码(Java中的客户端部分)。我如何确保完成?是否有一些重新发送命令与时间等?

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

这里是C代码段,其接收该数据:

所有的
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 
+0

你怎么知道数据包丢失? TCP是一种有保证的交付协议。这意味着如果写入或读取失败,那么将会出现错误。这可能是应用程序中的错误吗? –

+0

这是什么打我。 TCP是一个可靠的协议。我将发布我的C端服务器接收块的片段。这也可能是一个硬件问题。我是Java的noob,只是想确定是否有任何方法来重新发送数据包。当然,内核必须为协议可靠性做这件事......你怎么看它? – user489152

+0

数据包可能会丢弃在I/P层,但TCP会重新发送它们,并按发送顺序传送给接收方。我认为你的服务器或客户端存在一些错误。 –

回答

5

首先出现的是如在TCP/IP分组丢失这样的东西。该协议旨在以可靠的顺序可靠地发送字节流。所以问题必须出现在您的应用程序或其他方面。

我不是真正的心情来分析这个整体arraycopy()疯狂(C的人?),但你为什么不只是在发送一个全rbuffer经过BufferedOutputStream

然后:

os.write(rbuffer); 

相信我,BufferedOutputStream正在做同样的事情(收集到的字节块,并一次过向他们发送)。或者我错过了什么?

+0

@ user489152:因此,您在for循环中时数据会发生变化? – home

+0

没有数据不会改变。我已经设置了一个缓冲区,因为我担心我必须接收可能堵塞网络的大块,并且可能超出了TCP窗口。 – user489152

+0

@Tomasz:感谢您的意见。我不知道BufferedOutputStream。在此情况下,是否应该在C方面采取具体措施? – user489152

0

我以下面的方式改变了C面的程序,现在可:

    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; 
         } 
        } 
+1

你为什么从'remain'中减去'toGet'?如果你的'recv'(出于某些原因)读取的字节少于'toGet'字节,那么你将忽略流的结束。为了节省,你应该减去'recvMsgSize'。 –

+0

其中recvd + = recvMsgSize – user489152

+0

我看到我的recv函数被toGet-recvd字节,也没看到。 –

相关问题