2013-10-05 15 views
0

我目前正在使用C客户端(A),它将与作为RMI服务器(C)的客户端的Java服务器(B)进行通信。 A必须将它的参数发送给B,它将把它们发送给C,C将处理它们,将它们重新发送回B,然后B将它们返回给A.显然,A必须写入套接字,然后保持阻塞状态,直到B发送一些东西背部。我面临的问题是,在A写入套接字并且仍然被select()阻塞之后,B不会从其自己的readline中解除阻塞。使用C客户端和Java服务器时,BufferedReader readLine保持阻塞

如果我从A中删除select()和read(),那么一切都将完美工作。下面的代码

A-client.c

int err; 
    err = send(sockfd,(const char*)toSend,size,0);//send counter 
    if (err < 0){ 
     perror("Problem encountered while sending"); 
     exit(3); 
    } 
    //it always gets past this line 
    fd_set read_set; 
    int nb; 
    FD_ZERO(&read_set); //initialize variables for select 
    FD_SET(sockfd, &read_set); 
    nb = select(sockfd+1, &read_set, NULL, NULL, NULL); 
    if (nb!=0){ 
     if (FD_ISSET(sockfd, &read_set)) {//if data is incoming from*/ 

      char word[4096]=""; 
      if (read(sockfd, word, 4096) == 0){ 
       perror("The server terminated prematurely"); 
       exit(4); 
      } 
      for (i=0;i<4096;i++){ 
       printf("%c",word[i]); 
      } 
     } 
    } 

B-server.Java

connection = socket1.accept(); 
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream())); 
//it always passes this line 
String str = br.readLine(); 
//it passes this line only if i kill the C client or remove the read and select from the client 
String[] splitStr = str.split("\\s+"); 
int argsLen = splitStr.length; 
+0

想一想,试试'recv()'而不是'read'。并密切关注返回值,因为它是读取的字节数,或者错误时为负数。换句话说,它将*不*返回您正在测试的单个值。注意:需要一些组件。 (如在,你可能会得到你的数据块)。 – WhozCraig

+0

@WhozCraig read()和recv()在Windows上除外。 – EJP

+0

@EJP在nixes上*它们*在关闭连接时变为0?有趣。谢谢你的提示。 (是的,它的Windows通常使用它们,在Linux上是微不足道的东西)。 – WhozCraig

回答

3
  1. 您正在阅读的线路,但你写一行?用线路终结器?显然不是。

  2. 您忽略了read()在服务器中返回的计数。你不能假设read()填充了缓冲区。

+0

你是在现场!我以\ 0结束了该行,但是\ n有效。非常感谢! –