这几天有一个需求,需要用php通过socket通信的方式调用java的服务。但开发过程中总是出现php socket客户端出现连接被中断的情况,同时java socket服务器端实际已经正常接收到php socket传递过来的数据,但是服务器端无法回写给php socket客户端。而用java socket客户端调用时一切正常。下面分别列出两边的关键代码。
php客户端
- $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
- //设置超时时间为1秒
- socket_set_option($socket,SOL_SOCKET,SO_RCVTIMEO,array("sec"=>1, "usec"=>0 ) );
- $connection = socket_connect($socket, '127.0.0.1', 10008);
- if($connection<0){
- echo "can't connect";
- return;
- }
- $msg = iconv("utf-8","gbk","测试测试");;
- socket_write($socket,$msg,strlen($msg));
- $result = socket_read($socket,2048,PHP_NORMAL_READ);
- socket_close($socket);
java服务器端
- while(true){
- try {
- Socket s=ss.accept(); //这里的ss是已经初始化好的ServerSocket对象
- if(null!=s){
- BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
- PrintWriter out = new PrintWriter(s.getOutputStream(),true);
- String ininfo = in.readLine();
- System.out.println(info);
- in.close();
- out.close();
- s.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
调用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