Java 网络编程这块,说实在的,小编工作用的真少。确实没什么地方可用的啊,各种请求,公司都有封装好的工具,直接拿来呗。不过,Java Socket 在面试的时候被提及的不少。去年换工作就遇到了问 Java 网络编程的公司,当时小编好像没回答好,最终也确实没去成这家公司,不知道和这个叼毛的 Java Socket 有没有关系。反正不管怎么样,这块东西,歹学学!这次呢,咱们不谈太深,就举个例子,详细完整的展示一下 ServerSocket 和 Socket 通信是怎么个回事,真的不难,看不懂你就来我,好吧!Let go。
1,建立客户端。
/**
* @author: 小编 -- 皮皮克克
* @description: 客户端。
* @date: 2022/3/11
**/
public class SocketClient {
public static void main(String[] args) {
try {
//1, 和服务器创建连接 (ip 和端口是自定义的,本地测试为了方便,
//用的是 localhost:8080。如果各位有条件,可以用其他ip。端口也随意,和下面的
// ServerSocket serverSocket = new ServerSocket(8080); 端口保持一致就行)
Socket socket = new Socket("localhost",8080);
//2,编辑要发送给服务器的信息
OutputStream os = socket.getOutputStream();
PrintWriter pw = new PrintWriter(os);
pw.write("hello, 我是客户端");
pw.flush();
/**
* 客户端和服务器端建立连接后,服务器端会持续等待客户端传来的数据,如客户端写入数据后,
* 不执行shutdownOutput。
* 服务器端会一直等待,客户端和服务器端就会一直处于僵持状态。
* 执行shutdownOutput,关闭客户端输出流,服务器输入流也随之关闭
*/
socket.shutdownOutput();
//3,从服务器接收的信息
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String info = null;
while((info = br.readLine())!=null){
System.out.println("我是客户端,服务器返回信息:"+info);
}
//流是一个管道,连接内存和硬盘,用完后如果不关闭,会耗费(占用)很多资源
br.close();
is.close();
os.close();
pw.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
2,建立服务器端。
/**
* @author: 小编 -- 皮皮克克
* @description: 服务器端。
* @date: 2022/3/11
**/
public class SocketServer {
public static void main(String[] args) throws IOException {
InputStream is = null;
BufferedReader br = null;
OutputStream os = null;
PrintWriter pw = null;
try {
// 1,创建服务端socket
ServerSocket serverSocket = new ServerSocket(8080);
// 2, 创建客户端socket
Socket socket = new Socket();
//3,循环监听等待客户端的连接
while (true) {
// 监听客户端
socket = serverSocket.accept();
//打开输入流,获取客户端传来数据
is = socket.getInputStream();
br = new BufferedReader(new InputStreamReader(is));
String info = null;
while((info = br.readLine())!=null){
System.out.println("客户端发来:"+info + " 客户端IP:"
+ socket.getInetAddress().getHostAddress());
}
//关闭输入流
socket.shutdownInput();
//打开输出流,写入数据,传回客户端
os = socket.getOutputStream();
pw = new PrintWriter(os);
pw.write("服务器欢迎你");
pw.flush();
//关闭输出流
socket.shutdownOutput();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭流。
if (is != null){
is.close();
}
if (br != null){
br.close();
}
if (os != null){
os.close();
}
if (pw != null){
pw.close();
}
}
}
}
3,调用展示。分别启动两个 main() 方法。如果先启动 SocketClient,会报错 :
"C:\Program Files (x86)\Java\jdk1.8.0_31\bin\java.exe"
java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:211)
at com.cmbchina.SocketClient.main(SocketClient.java:16)
Process finished with exit code 0
所以应该先启动 SocketServer,再启动 SocketClient。
(1)SocketServer 控制台(服务器端会一直处于运行状态,可以持续接收客户端请求):
"C:\Program Files (x86)\Java\jdk1.8.0_31\bin\java.exe"
客户端发来:hello, 我是客户端。客户端IP:127.0.0.1
(2)SocketClient 控制台:
"C:\Program Files (x86)\Java\jdk1.8.0_31\bin\java.exe"
我是客户端,服务器返回信息:服务器欢迎你
Process finished with exit code 0