基于TCP协议Socket服务端和客户端的通信模型:
Socket通信步骤:
1.建立服务端ServerSocket和客户端Socket
2.打开连接到Socket的输出输入流
3.按照协议进行读写操作
4.关闭相对应的资源
多线程服务器
多线程用来实现 服务器与多客户端之间的通信
基本步骤
1 服务器创建serverSocket,循环调用accept()等待客户端连接
2 客户端创建一个scoket并请求和服务器端连接
3 服务器端接收客户端请求,创建socket与该客户建立专线连接
4 建立连接的连个socket在一个单独的线程上对话
5 服务器继续等待新的连接
客户端
1 package com.socket; 2 3 import java.io.BufferedReader; 4 import java.io.InputStream; 5 import java.io.InputStreamReader; 6 import java.io.OutputStream; 7 import java.io.PrintWriter; 8 import java.net.Socket; 9 10 public class Client { 11 12 /** 13 * 基于TCP协议的socket通信 14 * 客户端 15 * @return 16 */ 17 public static void main(String[] args) { 18 19 try { 20 //指定服务地址和端口号 21 Socket socket=new Socket("localhost", 8888); 22 //2.获取输出流,向服务器端发送信息 字节流 23 OutputStream op = socket.getOutputStream(); 24 //将输出流包装为打印流 25 PrintWriter ps = new PrintWriter(op); 26 ps.write("用户名 client 密码 123 "); 27 ps.flush(); 28 //关闭输出流 29 socket.shutdownOutput(); 30 31 //从服务器获取输入流 32 InputStream is = socket.getInputStream(); 33 BufferedReader bf = new BufferedReader(new InputStreamReader(is)); 34 String info = null; 35 36 while((info=bf.readLine())!=null){ 37 System.out.println("服务器说"+info); 38 } 39 40 //关闭资源 41 socket.close(); 42 } catch (Exception e) { 43 // TODO Auto-generated catch block 44 e.printStackTrace(); 45 } 46 } 47 48 }
服务器端
1 package com.socket; 2 3 4 import java.io.IOException; 5 import java.net.InetAddress; 6 import java.net.ServerSocket; 7 import java.net.Socket; 8 9 public class Server { 10 11 /** 12 * 基于TCP协议的Socket编程 13 * 服务器端 14 * @return 15 */ 16 public static void main(String[] args) { 17 18 int count = 0; 19 try { 20 //1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口 21 ServerSocket serverSocket = new ServerSocket(8888); 22 //循环监听客户端连接 23 while(true){ 24 // 调用accept()方法开始监听,等待客户端的连接 25 Socket socket=serverSocket.accept(); 26 SocketThread st = new SocketThread(socket); 27 28 st.start(); 29 count++; 30 System.out.println("当前客户数量: "+count); 31 32 InetAddress address=socket.getInetAddress(); 33 34 System.out.println("当前客户端ip"+address); 35 } 36 37 38 } catch (IOException e) { 39 40 e.printStackTrace(); 41 } 42 43 44 } 45 46 }
服务器端线程类
1 package com.socket; 2 3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.io.InputStreamReader; 7 import java.io.OutputStream; 8 import java.io.PrintWriter; 9 import java.net.Socket; 10 11 public class SocketThread extends Thread { 12 13 /** 14 * 循环接收客户端线程 15 * 16 * @return 17 */ 18 // 和本线程相关的Socket 19 Socket socket = null; 20 public SocketThread(Socket socket) { 21 this.socket = socket; 22 } 23 24 @Override 25 public void run() { 26 27 InputStream is = null; 28 OutputStream os = null; 29 BufferedReader bs = null; 30 PrintWriter pw = null; 31 try { 32 is = socket.getInputStream(); 33 34 bs = new BufferedReader(new InputStreamReader(is)); 35 String info = null; 36 while ((info = bs.readLine()) != null) { 37 38 System.out.println("我是服务器 客户端 说 " + info); 39 } 40 socket.shutdownInput(); 41 42 // 相应客户端信息 43 os = socket.getOutputStream(); 44 pw = new PrintWriter(os); 45 pw.print("你好,欢迎登陆"); 46 pw.flush(); 47 } catch (IOException e) { 48 // TODO Auto-generated catch block 49 e.printStackTrace(); 50 } finally { 51 52 try { 53 if (os != null) 54 os.close(); 55 if (is != null) 56 is.close(); 57 if (bs != null) 58 bs.close(); 59 if (pw != null) 60 pw.close(); 61 if (socket != null) 62 socket.close(); 63 } catch (IOException e) { 64 // TODO Auto-generated catch block 65 e.printStackTrace(); 66 } 67 68 } 69 } 70 71 }