Java与PHP之间的Socket通信

Java作为服务端

Java端作为服务端,PHP端作为客户端,在之前一篇文章中说了下PHP作为客户端如何与Java端进行通信。由于业务需要,socket必须等待服务端处理完成,并返回处理结果给PHP端。在这里主要说明一下Java端如何处理的,不足之处,望指正。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
ServerSocket serverSocket = new ServerSocket(port); //创建绑定到特定端口的服务器套接字
Socket socket = serverSocket.accept(); //侦听并接受到此套接字的连接

InputStream inputStream = socket.getInputStream();
StringBuilder sb = new StringBuilder();

byte[] packetLength = new byte[4];
inputStream.read(packetLength, 0, 4); //首先从套接字中读取4字节的数据长度
int target = byteToint(packetLength); //这里将字节数组转换成整数
System.out.println("message size:" + target);

byte[] bytes = new byte[target];
inputStream.read(bytes); //读取指定长度的数据
sb.append(new String(bytes, 0, target, "UTF-8"));
System.out.println("get message " + sb);

String result = "has receive message";
OutputStream outputStream = socket.getOutputStream();
int responseLength = result.getBytes().length; //这个地方的长度,一定要是字节数组的长度,否则如果字符串中包含中文,接收端接收数据会不完整
byte[] targets = intTobyte(responseLength);
outputStream.write(targets); //首先发送4个字节的数据大小
outputStream.write(result.getBytes()); //再发送真正的数据

outputStream.flush();
outputStream.close();
inputStream.close();
socket.close();

上述代码需要处异常,而且代码中的byteToint和intTobyte这两个函数非原创,是其他博主的劳动成果,感谢这位作者,原文地址https://www.cnblogs.com/langren1992/p/4717241.html

PHP作为服务端

相关函数: socket_create、socket_set_block、socket_bind、socket_listen、socket_accept、socket_read、socket_write,这些函数具体参数说明在PHP文档上写很详细,这里就不再赘述,这里只是介绍服务端如何处理请求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//确保在连接客户端时不会超时
set_time_limit(0);
//设置IP和端口号
$address = "127.0.0.1";
$port = 54321;
$socketServer = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("socket_create() fail:" . socket_strerror(socket_last_error()) . "/n");
//设置为阻塞模式
socket_set_block($socketServer) or die("socket_set_block() fail:" . socket_strerror(socket_last_error()) . "/n");
//绑定端口
$result = socket_bind($socketServer, $address, $port) or die("socket_bind() fail:" . socket_strerror(socket_last_error()) . "/n");
//开始监听
$result = socket_listen($socketServer, 4) or die("socket_listen() fail:" . socket_strerror(socket_last_error()) . "/n");

do {
//接收连接请求并返回一个子Socket来处理客户端和服务器间的信息
$sock = socket_accept($socketServer) or die("socket_accept() failed: reason: " . socket_strerror(socket_last_error()) . "/n");
while($sock){
//读取客户端数据
echo "Read client data \n";

$length = socket_read($sock, 4);
$length = unpack('i', $length);
echo "length:$length[1] \n";

$request = socket_read($sock, $length[1]);
echo "$request:$request \n";


//数据传送 向客户端写入返回结果
$msg = "this is response message \n";
$msgLength = strlen($msg);
$msgLength = pack('i', $msgLength);
socket_write($sock, $msgLength);
socket_write($sock, $msg, strlen($msg)) or die("socket_write() failed: reason: " . socket_strerror(socket_last_error()) ."/n");
break;
}

} while (true);
//根据需要关闭socket
socket_close($socketServer);

在接收到客户端的请求后,可以结合PHP的多线程进行处理,这里只是简单的返回字符串。

总结

各大语言实现socket通信的方式都是大同小异,在服务端的流程都是差不多的。在有现成高性能socket通信框架的情况下,建议不要自己去实现,但是得理解框架底层是怎样实现的。