2010-07-06 90 views
1

我正在研究客戶端服務器體系結構,我只是初學者。這裏我的服務器是C的,客戶端是Java,我想從C服務器向Java客戶端發送一個大小爲10-20MB的二進制/數據庫(.db)/映像文件。通過java中的套接字發送大量數據

服務器端的C代碼是:

int sockfd, newsockfd, portno, clilen; 

struct sockaddr_in serv_addr, client_addr; 

sockfd = socket(AF_INET, SOCK_STREAM, 0); 
if(sockfd < 0) 
{ 
    strcpy(message,"Error opening socket"); 
    eFlag = 1; 
    send_message(message); 
} 

bzero((char *)&serv_addr, sizeof(serv_addr)); 
portno = 6789; 
serv_addr.sin_family = AF_INET; 
serv_addr.sin_addr.s_addr = INADDR_ANY; 
serv_addr.sin_port = htons(portno); 

if(bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) 
{ 
    strcpy(message,"Error on binding"); 
    eFlag = 1; 
    send_message(message); 
} 

listen(sockfd, 5); 
clilen = sizeof(client_addr); 
newsockfd = accept(sockfd, (struct sockaddr *)&client_addr, &clilen); 

if(newsockfd < 0) 
{ 
    strcpy(message,"Error on accept"); 
    eFlag = 1; 
    send_message(); 
    exit(4); 
} 

void send_file() 
{ 
    buffer = (char *)malloc(sizeof(char)*lSize); 

    result = fread(buffer, sizeof(char), lSize, fp); 
    printf("\n\n########## data read into buffer successfully #######"); 


    if(newsockfd) 
    { 
     n = send(newsockfd, buffer, lSize); 
     printf("\n\n$$$$$$$$ Data sent successfully $$$$$"); 
     strcpy(message,"Data sent successfully"); 
     send_message(message); 
    } 


    else 
    { 
     strcpy(message, "Error writing on socket"); 
     send_message(message); 
    } 

    sleep(sleepTime); 
    sleepTime = (int) (sleepTime*1.02); 

    free(buffer); 
} 

而且,我的客戶端的Java代碼:

    final int PORT_NO = 6789; 
     final String Server_name = "192.133.133.1"; 
     Socket m_socket = null; 
     String str; 
     int ch; 

    try { 
     if(m_socket == null) 
      m_socket = new Socket(Server_name, PORT_NO); 
     if(m_socket == null) 
      System.out.println("Unable to open the socket"); 


    DataInputStream dis = new DataInputStream(m_socket.getInputStream()); 
    PrintStream ps = new PrintStream(m_socket.getOutputStream()); 

    DataInputStream ds = new DataInputStream(System.in); 

    while(true) 
    { 
     System.out.println("1. Synchronize"); 
     System.out.println("2. Exit"); 
     System.out.println("Enter your choice..."); 
     str = ds.readLine(); 
     ch = Integer.parseInt(str); 

     switch(ch) 
     { 
     case 1: 
    ps.println("<message action='buttonpress' value='synchronize' />"); 
    System.out.println("avilable data to read is:"+dis.available()); 
    FileOutputStream fos = new FileOutputStream("mukul.db"); 



      byte data[] = new byte[102400]; //100 Kb byte array 

          dis.read(data); 


      String str_data = new String(data); 
      str_data = str_data.trim(); 
      data = str_data.getBytes(); 

      fos.write(data); 
      fos.close(); 

      break; 

這裏的數據僅部分閱讀,但在實施下面的代碼數據丟失即大約10kb或更少。

我只是這樣的職位的初學者,我的代碼可能很繁瑣,所以請忽略發佈中的所有錯誤。

因此,請告訴我如何在此客戶端 - 服務器架構中接收1 MB/10 MB的數據,而不會丟失數據。

如果我在C代碼中使用「sendfile(out_fp,in_fp,pos,len)」方法而不是「send()」會怎麼樣?這個方法發送文件句柄。那麼在Java中相應的函數將捕獲文件句柄。

預先感謝您。

回答

0
  1. 在您致電m_socket = new Socket(...)後,m_socket不可能爲空。它將引發異常或將Socket指定給m_socket,從不爲空。所以這個測試是毫無意義的。

  2. 在您撥打readLine()之後,您必須檢查空返回值,這意味着EOS,這意味着另一端已關閉連接,這意味着您必須退出讀取循環並關閉套接字。

  3. 正如它在Javadoc中所述,InputStream.available()不應該用於EOS測試。它的合同是返回可被讀取的字節數而不被阻塞。這很少與通過套接字傳入文件的長度相同。你必須保持閱讀的插座,直至EOS:

    int count; 
    byte[] buffer = new byte[8192]; 
    while ((count = in.read(buffer)) > 0) 
        out.write(buffer, 0, count); 
    

如果你的發送端,當發送完,你將不得不做提前發送文件的文件長度的文件不關閉套接字,並修改上面的循環來精確讀取許多字節。

+0

謝謝你,它幫助我從服務器發送數據成功。 – user268758 2010-07-07 12:26:03

1

您正在濫用send()/ recv()函數。由於可能存在於內核中的限制,send()和recv()不需要發送儘可能多的數據。您必須一遍又一遍地調用send(),直到所有數據都被推送完畢。

例如爲:

int sent = 0; 
int rc; 
while (sent < should_send) 
{ 
    rc = send(sock, buffer + sent, should_send - sent, 0); 
    if (rc <= 0) // Error or hangup 
     // do some error handling; 

    sent += rc; 
} 
+0

謝謝。它幫助客戶成功接收數據。 – user268758 2010-07-07 12:23:02

1

Java方面,

int lent2 = 0; 
int LengthToReceive = 102400; 
char[] chTemp = new char[LengthToReceive]; 

while (true) { 

    int readlength = bufferedreader.read(chTemp, lent2,LengthToReceive - lent2); 
    if(readlength==-1){ 
     break; 
    } 

    lent2 += readlength; 
    if (lent2 >= LengthToReceive) { 
     flag = false; 
     break; 
    } 
}