java - Java Socket 监听 PHP 客户端不工作
问题描述
我在运行 PHP 客户端向 Java 服务器发送数据时遇到问题,问题是 Java 服务器没有显示来自 PHP 客户端的任何输入流。
当我执行 php 客户端时,Java 服务器输出仅显示“刚刚连接..”,我期待它显示“正在测试”,这是 java 代码:
Waiting for client on port 3000...
Waiting for client on port 3000...
Waiting for client on port 3000...
Waiting for client on port 3000...
Just connected to /127.0.0.1:39220
Waiting for client on port 3000...
PHP客户端输出:
$ sudo php testSocketClient.php
Try to connect '127.0.0.1' Port '3000'...
Connect OK
Send Message to Server Successfully!
Send Information:Testing
Turn Off Socket...
Turn Off OK
这是我的 PHP 客户端代码,这是我发送“测试”消息的地方:
<?php
set_time_limit(0);
$port = 3000;
$ip = "127.0.0.1";
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if($socket < 0) {
echo "socket_create() Fail to create:".socket_strerror($sock)."\n";
} else {
echo "Try to connect '$ip' Port '$port'...\n";
$result = socket_connect($socket, $ip, $port);
if ($result < 0) {
echo "socket_connect() failed.\nReason: ($result) " . socket_strerror($result) . "\n";
}else {
echo "Connect OK\n";
$in = "Testing\r\n";
$out = '';
if(!socket_write($socket, $in, strlen($in))) {
echo "socket_write() failed. reason: " . socket_strerror($socket) . "\n";
}else {
echo "Send Message to Server Successfully!\n";
echo "Send Information:" . $in . "\n";
echo "Turn Off Socket...\n";
socket_close($socket);
echo "Turn Off OK\n";
}
}
}
这是我的 Java 服务器代码:
package TestPackage;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
public class TestSocketListener {
public static void main(String[] args) {
System.out.println("INIT SOCKET");
int port = 3000;
while(true) {
try {
ServerSocket serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(5000);
System.out.println("Waiting for client on port " +
serverSocket.getLocalPort() + "...");
Socket server = serverSocket.accept();
System.out.println("Just connected to " + server.getRemoteSocketAddress());
DataInputStream DataInStream = new DataInputStream(server.getInputStream());
System.out.println(DataInStream.readUTF());
DataOutputStream DataOutStream = new DataOutputStream(server.getOutputStream());
DataOutStream.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress()
+ "\nGoodbye!");
server.close();
System.out.println(("SERVER CLOSED"));
} catch(SocketTimeoutException st) {
//System.out.println("Socket timed out!");
} catch(SocketException s) {
//System.out.println("Socket Error!!");
//s.getMessage();
} catch (IOException e) {
//System.out.println("IO Error!");
}
}
}
}
这是使用异常时的错误消息(尝试使用不同的端口时发生相同的错误。我正在尝试 3000、4444 和 29299):
java.net.BindException: Address already in use (Bind failed)
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387)
at java.net.ServerSocket.bind(ServerSocket.java:375)
at java.net.ServerSocket.<init>(ServerSocket.java:237)
at java.net.ServerSocket.<init>(ServerSocket.java:128)
at TestPackage.TestSocketListener.main(TestSocketListener.java:17)
当前使用的端口:
$ nmap 127.0.0.1
Starting Nmap 6.40 ( http://nmap.org ) at 2019-08-01 17:32 WIB
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00046s latency).
Not shown: 994 closed ports
PORT STATE SERVICE
22/tcp open ssh
25/tcp open smtp
80/tcp open http
111/tcp open rpcbind
443/tcp open https
3306/tcp open mysql
解决方案
我让它工作。根据 JAVA 文档,IOException
如果客户端关闭连接,则可能发生。请参阅:数据输入流。您的 PHP 代码执行并结束连接。但这仍然不是您的 PHP 代码的问题。您使用的readUTF()
方法并没有真正告诉 JAVA 要读取多少字节;这不可靠。相反,使用read([]byte b, int off, int len)
这是我的输出:
INIT SOCKET
Waiting for client on port 3000...
Just connected to /127.0.0.1:61989
Testing
SERVER CLOSED
这是代码更改:
package TestPackage;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.nio.channels.IllegalBlockingModeException;
public class TestSocketListener {
public static void main(String[] args) {
System.out.println("INIT SOCKET");
int port = 3000;
while(true) {
try {
ServerSocket serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(5000);
System.out.println("Waiting for client on port " +
serverSocket.getLocalPort() + "...");
Socket server = serverSocket.accept();
System.out.println("Just connected to " + server.getRemoteSocketAddress());
// you want to know how much bytes to read
InputStream inputstream = server.getInputStream();
int buflen = inputstream.available();
DataInputStream DataInStream = new DataInputStream(inputstream);
byte[] rawstring = new byte[buflen];
DataInStream.read(rawstring, 0, buflen);
String str = new String(rawstring);
System.out.println(str);
DataOutputStream DataOutStream = new DataOutputStream(server.getOutputStream());
DataOutStream.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress()
+ "\nGoodbye!");
server.close();
System.out.println(("SERVER CLOSED"));
} catch(SocketTimeoutException st) {
System.out.println("Socket timed out!");
} catch(SocketException s) {
//System.out.println("Socket Error!!");
//s.getMessage();
} catch (IOException e) {
//System.out.println("IO Error!");
}
}
}
}
希望这可以帮助!
推荐阅读
- mongodb - MongoDB:如果属性存在,则获取数组的最后一个元素
- python - 如何使用装饰器将类的方法添加到类内的列表中
- javascript - 我如何知道 JavaScript 自动返回非原始/用户定义类型和承诺的类型?
- visual-studio - 安装 VCPKG 之后对“vcpkg install”的任何调用都会导致“更改工作目录失败”
- reactjs - 如何根据文件阅读器发出的事件测试反应组件
- json.net - JSONConvert.SerializeObject 最大长度
- python - 模块 tensorflow.tools.api.generator.api.compat 没有属性 v1
- ruby-on-rails - 在 Ruby on Rails 应用程序中作为 Ruby Gem 的可继承 Rake 任务
- reactjs - 将复选框列表值从子级传递给父级
- sql - 如何在 Redshift 上将 varchar 转换为时间-“列“持续时间”具有不受支持的类型“没有时区的时间”