网络编程实战
即时通信
-
即时通信,指一个客户端的消息发出去,其他客户端可以接收到
-
即时通讯需要进行端口转发的设计思想
-
package com.wly.TCP_SMS; import java.io.*; import java.net.Socket; import java.util.Scanner; //客户端发消息 //客户端随时收消息 public class ClientSocketDemo1 { public static void main(String[] args) { System.out.println("====客户端====="); try { //创建独立线程负责客户端读消息(服务器随时可能发消息过来) Socket socket=new Socket("127.0.0.1",7777); //创建一个独立线程专门负责客户端的读消息 new ClientReaderThread(socket).start(); //从Socket通信管道得到一个字节输出流,负责发送数据 OutputStream os=socket.getOutputStream(); //把低级的字节流包装成打印流 PrintStream ps=new PrintStream(os); //发送消息 Scanner sc=new Scanner(System.in); while (true){ System.out.println("请说:"); String msg=sc.nextLine(); ps.println(msg); ps.flush(); } } catch (IOException e) { e.printStackTrace(); } } } class ClientReaderThread extends Thread{ private 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( "收到消息:" + msg); } } catch (IOException e) { System.out.println("服务端把你踢出去了"); } } public ClientReaderThread(Socket socket) { this.socket = socket; } }
-
package com.wly.TCP_SMS; import com.wly.TCP.ServerReaderRunnable; import javax.sound.sampled.Line; import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List; import java.util.concurrent.*; //服务器 public class ServerSocketDemo1 { //定义list集合,存储当前在线的socket管道 public static List<Socket> allOnineSocket=new ArrayList<>(); public static void main(String[] args) { //注册端口 ServerSocket serverSocket; try { System.out.println("服务端启动"); serverSocket = new ServerSocket(7777); //调用accept方法:等待接受客户端的Socket连接请求,建立Socket通信管道 while (true) { Socket socket=serverSocket.accept(); System.out.println(socket.getRemoteSocketAddress()+"上线了"); allOnineSocket.add(socket);//上线存储 new ServerReaderThread(socket).start(); } } catch (IOException e) { e.printStackTrace(); } } } class ServerReaderThread extends Thread{ private Socket socket; @Override public void run() { try { InputStream is = socket.getInputStream(); //把字节输入流包装成缓冲字符输入流进行消息的接受 BufferedReader br = new BufferedReader(new InputStreamReader(is)); String Line; while ((Line = br.readLine()) != null) {//收到一行消息,一发一收 System.out.println(socket.getRemoteSocketAddress() + "说了:" + Line); //把这个消息进行端口转发给全部客户端socket管道 sendMsToAll(Line); } } catch (IOException e) { System.out.println(socket.getRemoteSocketAddress()+"下线了"); ServerSocketDemo1.allOnineSocket.remove(socket); } } private void sendMsToAll(String msg) throws IOException { for (Socket socket : ServerSocketDemo1.allOnineSocket) { PrintStream ps=new PrintStream(socket.getOutputStream()); ps.println(msg); ps.flush(); } } public ServerReaderThread(Socket socket) { this.socket = socket; } }
模拟BS系统
package com.wly.BS;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;
public class BSserverDemo {
private static ExecutorService pool=new ThreadPoolExecutor(3,5,
6, TimeUnit.SECONDS,new ArrayBlockingQueue<>(2),
Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
public static void main(String[] args) {
try {
ServerSocket ss=new ServerSocket(9090);
while (true){
Socket socket=ss.accept();
pool.execute(new ServerReaderRunnable(socket));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.wly.BS;
import java.io.*;
import java.net.Socket;
public class ServerReaderRunnable implements Runnable{
private Socket socket;
public ServerReaderRunnable(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
//浏览器已与本线程建立Socket管道
//响应给浏览器显示
try {
PrintStream ps=new PrintStream(socket.getOutputStream());
ps.println("HTTP/1.1 200 OK");//协议类型和版本,响应成功
ps.println("Content-Type:text/html;charset=UTF-8");//响应数据的类型文本或网页
ps.println();//必须发送一个空行
//才可以给浏览器响应
ps.println("<span style='color:red;font-size:70px'>zhaoxiaoer</span>");
ps.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}