1. 简单的 C/S 程序
public class BIOServer {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("服务启动成功");
while (!serverSocket.isClosed()) {
Socket requset = serverSocket.accept();
System.out.println("收到新连接" + requset.toString());
InputStream inputStream = requset.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
String msg;
while ((msg = bufferedReader.readLine()) != null) {
if (msg.length() == 0) {
break;
}
System.out.println(msg);
}
System.out.println("收到数据,来自" + requset.toString());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
首先要在服务端new ServerSocket
,这是 Java 程序提供好的,它会去监听指定的端口。
如果需要接收客户端发送给的请求的话,需要调用它的accept()
方法,这个方法是阻塞
的,所谓阻塞就是如果没有收到请求的话,这个方法会一直等待,从方法注释中可以看到这个阻塞的提示

这个例子通过请求 socket 对象,配合 io 操作把收到的请求打印出来。
下面是客户端的代码
public class BIOClient {
public static void main(String[] args) {
try {
Socket socket = new Socket("localhost", 8080);
OutputStream outputStream = socket.getOutputStream();
Scanner scanner = new Scanner(System.in);
System.out.println("请输入");
String smg = scanner.nextLine();
outputStream.write(smg.getBytes(StandardCharsets.UTF_8));
scanner.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
启动服务端,然后客户端使用socket
对象配合 io 将数据发送给客户端,输入今天是个好日子
请输入
今天是个好日子
Process finished with exit code 0
因为OutputStream
也是阻塞的,所以看到程序退出,就说明发送成功了。
再看服务端的输出,如下
服务启动成功
收到新连接Socket[addr=/127.0.0.1,port=11956,localport=8080]
今天是个好日子
收到数据,来自Socket[addr=/127.0.0.1,port=11956,localport=8080]
2. 多线程处理
这个服务端接到一个连接后,其他连接就只能等待第一个连接结束,明显不符合使用要求。
因为阻塞是阻塞的线程,所以可以在处理的部分加入多线程的处理,这样就可以同时处理多个连接。
public class BIOServer2 {
private static ExecutorService threadPool = Executors.newCachedThreadPool();
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("服务启动成功");
while (!serverSocket.isClosed()) {
Socket requset = serverSocket.accept();
System.out.println("收到新连接" + requset.toString());
threadPool.execute(() -> {
try {
InputStream inputStream = requset.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
String msg;
while ((msg = bufferedReader.readLine()) != null) {
if (msg.length() == 0) {
break;
}
System.out.println(msg);
}
System.out.println("收到数据,来自" + requset.toString());
} catch (IOException e) {
e.printStackTrace();
}
});
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
启动服务端,然后同时启动两个客户端,输入不同的文字,都能打印出来
服务启动成功
收到新连接Socket[addr=/127.0.0.1,port=12053,localport=8080]
收到新连接Socket[addr=/127.0.0.1,port=12063,localport=8080]
123
收到数据,来自Socket[addr=/127.0.0.1,port=12053,localport=8080]
456
收到数据,来自Socket[addr=/127.0.0.1,port=12063,localport=8080]
3.回应 HTTP 请求
在浏览器中输入127.0.0.1:8080
,会显示如下的错误消息

但是后台是能够接收到数据的
服务启动成功
收到新连接Socket[addr=/127.0.0.1,port=12284,localport=8080]
收到新连接Socket[addr=/127.0.0.1,port=12285,localport=8080]
GET / HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.158 Safari/537.36 Vivaldi/2.5.1525.43
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
收到数据,来自Socket[addr=/127.0.0.1,port=12284,localport=8080]
这时在request
的输出流中加入 HTTP 的响应报文,浏览器就能显示出来了

public class BIOServer3 {
private static ExecutorService threadPool = Executors.newCachedThreadPool();
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("服务启动成功");
while (!serverSocket.isClosed()) {
Socket requset = serverSocket.accept();
System.out.println("收到新连接" + requset.toString());
threadPool.execute(() -> {
try {
InputStream inputStream = requset.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
String msg;
while ((msg = bufferedReader.readLine()) != null) {
if (msg.length() == 0) {
break;
}
System.out.println(msg);
}
System.out.println("收到数据,来自" + requset.toString());
OutputStream outputStream = requset.getOutputStream();
outputStream.write("HTTP/1.1 200 OK\r\n".getBytes());
outputStream.write("Content-Length: 11\r\n\r\n".getBytes());
outputStream.write("Hello World".getBytes());
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (requset != null)
requset.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
网友评论