网络编程之TCP通信
聊天室的实现,多发多收
Server端 主线程定义了循环负责接收客户端Socket管道连接 每接收到一个Socket通信管道后分配一个独立的线程负责处理它。 处理的方式为: 1、从socket通信管道得到一个字节输入流 2、把字节输入流包装成缓冲字符输入流进行消息的接收 3、按照行读取消息 Client端 1、创建Socket通信管道请求有服务端的连接 2、从socket通信管道中得到一个字节输出流 负责发送数据
Server
public class ServerDemo2 {
public static void main(String[] args) {
try {
System.out.println("===服务端启动成功===");
ServerSocket serverSocket = new ServerSocket(7777);
while (true) {
Socket socket = serverSocket.accept();
System.out.println(socket.getRemoteSocketAddress()+ "它来了,上线了!");
new ServerReaderThread(socket).start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Client
public class Server{
public static void main(String[] args) throws IOException {
System.out.println("服务端启动");
DatagramSocket socket = new DatagramSocket(6666);
byte[] buffer = "厦大百年生日快乐".getBytes();
DatagramPacket packet = new DatagramPacket(buffer,buffer.length,
InetAddress.getLocalHost(),8888);
socket.send(packet);
socket.close();
}
}
ServerReaderThread类:处理线程
public class ServerReaderThread extends Thread{
private Socket socket;
public ServerReaderThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try {
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String msg;
while ((msg = br.readLine()) != null){
System.out.println(socket.getRemoteSocketAddress() + "说了:: " + msg);
}
} catch (Exception e) {
System.out.println(socket.getRemoteSocketAddress() + "下线了!!!");
}
}
}
改进:使用线程池优化
客户端与服务端的线程模型是: N-N的关系。 客户端并发越多,系统瘫痪的越快。
使用线程池,适合局域网,但不适合并发。
Server端
public class ServerDemo2 {
private static ExecutorService pool = new ThreadPoolExecutor(300,
1500, 6, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(2)
, Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
public static void main(String[] args) {
try {
System.out.println("===服务端启动成功===");
ServerSocket serverSocket = new ServerSocket(6666);
while (true) {
Socket socket = serverSocket.accept();
System.out.println(socket.getRemoteSocketAddress()+ "它来了,上线了!");
Runnable target = new ServerReaderRunnable(socket);
pool.execute(target);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
|