这几天有一个需求,需要用php通过socket通信的方式调用java的服务。但开发过程中总是出现php socket客户端出现连接被中断的情况,同时java socket服务器端实际已经正常接收到php socket传递过来的数据,但是服务器端无法回写给php socket客户端。而用java socket客户端调用时一切正常。下面分别列出两边的关键代码。

php客户端

 
  
  1. $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);  
  2.         //设置超时时间为1秒       
  3.         socket_set_option($socket,SOL_SOCKET,SO_RCVTIMEO,array("sec"=>1, "usec"=>0 ) );  
  4.            
  5.         $connection = socket_connect($socket'127.0.0.1', 10008);  
  6.         if($connection<0){  
  7.             echo "can't connect";  
  8.             return;  
  9.         }  
  10.         $msg = iconv("utf-8","gbk","测试测试");;  
  11.         socket_write($socket,$msg,strlen($msg));  
  12.         $result = socket_read($socket,2048,PHP_NORMAL_READ);  
  13.         socket_close($socket); 

java服务器端

 
  
  1. while(true){  
  2.         try {  
  3.             Socket s=ss.accept(); //这里的ss是已经初始化好的ServerSocket对象  
  4.             if(null!=s){  
  5.                 BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));  
  6.                 PrintWriter out = new PrintWriter(s.getOutputStream(),true);  
  7.                 String ininfo = in.readLine();  
  8.                 System.out.println(info);  
  9.                 in.close();  
  10.                 out.close();  
  11.                 s.close();  
  12.             }  
  13.         } catch (IOException e) {  
  14.             e.printStackTrace();  
  15.         }  
  16.     } 

调用php客户端时出现的错误提示

Warning: socket_read() [function.socket-read]: unable to read from socket [0]

问题原因:由于java服务器接收时,使用的是readline,即收到了\n的标记时才表示接受完成,而php发送数据时,没有加\n,表示接收一直没有完成,因此一直阻塞(java客户端一般发送数据时使用println(),默认带了\n,所以java客户端正常运行),无法向客户端回写数据。而如果客户端设置了连接超时时间,则出现服务器端主动断开连接的错误。

解决方法:在php socket客户端要发送的数据末尾加上"\n"即可解决问题。

参考资料:http://stackoverflow.com/questions/11488925/php-tcp-connection-to-java-server-hangs-on-socket-read