Client端
package com.athairen.bio;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
import java.util.Scanner;
import java.util.Stack;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
public class BioClient {
private static final String EXIT_STR="exit";
public static void main(String[] args) throws IOException {
ExecutorService threadPool= Executors.newCachedThreadPool();
Socket socket=new Socket("127.0.0.1",6666);
OutputStream outputStream = socket.getOutputStream();
InputStream inputStream = socket.getInputStream();
threadPool.execute(new Runnable() {
@Override
public void run() {
byte[] buffer=new byte[1024];
int length;
try {
while ((length=inputStream.read(buffer))!=-1) {
String s=new String(buffer,0, length);
System.out.println(s);
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
System.out.println("输入消息:");
String inputStr="";
while (!inputStr.toLowerCase(Locale.ROOT).equals(EXIT_STR)){
Scanner scanner=new Scanner(System.in);
inputStr = scanner.next();
outputStream.write(inputStr.getBytes(StandardCharsets.UTF_8));
outputStream.flush();
}
inputStream.close();
outputStream.close();
socket.shutdownInput();
socket.shutdownOutput();
if(!socket.isClosed()){
socket.close();
}
System.out.println("client programe exit");
}
}
server端
package com.athairen.bio;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class BioServer {
public static void main(String[] args) throws IOException {
//create a thread pool
ExecutorService threadPool = Executors.newCachedThreadPool();
ServerSocket serverSocket = new ServerSocket(6666);
System.out.println("server start");
while (true) {
final Socket client = serverSocket.accept();
System.out.println("one client connected server");
threadPool.execute(new Runnable() {
@Override
public void run() {
try {
handler(client);
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
public static void handler(Socket client) throws IOException {
if(!client.isConnected()){
client.shutdownInput();
client.shutdownOutput();
if(!client.isClosed()){
client.close();
}
}
System.out.println("thread:: " + Thread.currentThread().getId() + " -- " + Thread.currentThread().getName());
OutputStream outputStream = client.getOutputStream();
InputStream inputStream = client.getInputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
String s=new String(buffer, 0, len);
System.out.println(s);
outputStream.write(("hello,client,welcome!! your send content is: " + s).getBytes(StandardCharsets.UTF_8));
outputStream.flush();
}
}
}
需要注意的地方:
短连接与长连接的不同:短连接将在shutdow流之后对应的socket也将会被关闭,所以我们在使用短连接时应该在流和socket关闭后,重新连接即new 一个新的socket,而长连接不应该关闭流和socket对象也不能shutdown流,而应该在写buffer时flush output流,注意!!,因此长连接的内存占用会高一些,也由于BIO的同步阻塞导致我们的服务器不能处理大量并发,因此更推荐使用NIO(同步非阻塞)框架netty,或AIO(异步非阻塞)。
注:
NIO更适合处理大量请求且少量资源(处理高并发字符串消息)的情况
AIO更适合处理大量请求且大量资源的情况(处理高并发且处理图片数据)的情况,但目前尚不成熟。
????????
|