2010-07-06 91 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; 
    } 
}