版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qinshi965273101/article/details/81516574
1、通过BIO了解 Socket编程
BIO就是传统的IO,是同步阻塞式IO。
阻塞/非阻塞:从线程的角度来考虑的,线程挂起,不再抢夺cpu资源,则称为线程被阻塞。
同步/异步:从并发参与者的角度考虑,多个参与者是否需要互相等待协调,如果任务的执行需要互相等待,互相协调,则为同步。
下面的例子中使用到 accept(),read() 两个方法都是阻塞式的。例如执行到read() 方法,若没有数据可以读,则线程会挂起。直到有数据写进来才往下继续执行。
使用传统的BIO实现socket通信,由于阻塞特性,线程会一直等待某一个客户端请求,浪费线程资源。下面的例子中,每一个客户端连接到服务端都创建一个线程去处理,但是线程的数量是有上限的。
package day01.bio;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketServer {
public static void main(String[] args) throws Exception {
//1、创建一个服务端
ServerSocket ss = new ServerSocket(1234);
while(true) {
//2、等待客户端连接,并拿到客户端对应的Socket实例
Socket socket = ss.accept();
//3、只要有客户端连接,就会创建一个线程去维护这个连接
new Thread(new ssRunnable(socket)).start();
}
}
}
class ssRunnable implements Runnable{
private Socket socket;
public ssRunnable(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
InputStream in = socket.getInputStream();
//规定好每次最多接受和发送的数据量
byte[] data = new byte[1024];
int len = 0;
//如果客户端一直不写内容,read会一直阻塞等待读取内容
if((len=in.read(data))!=-1) {
System.out.println(new String(data, 0, len, "utf-8"));
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package day01.bio;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
public class SocketClient {
public static void main(String[] args) throws IOException {
//1、创建一个客户端
Socket socket = new Socket();
//2、连接服务端
socket.connect(new InetSocketAddress("127.0.0.1", 1234));
OutputStream out = socket.getOutputStream();
out.write("我是客户端001,正在发送请求给服务端!".getBytes("utf-8"));
out.flush();
socket.close();
}
}