一、Socket简介
Socket通信实现步骤
1.创建ServerSocket和Socket
2.打开连接到Socket的输入/输出流
3.按照协议对Socket进行读/写操作
4.关闭输入输出流、关闭Socket
二、编程实现基于TCP的Socket通信之服务端与客户端
服务器端:
1.创建ServerSocket对象,绑定监听端口
2.通过accept()方法监听客户端请求
3.连接建立后,通过输入流读取客户端发送的请求信息
4.通过输出流向客户端响应信息
5.关闭相关资源
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStream; 4 import java.io.InputStreamReader; 5 import java.net.ServerSocket; 6 import java.net.Socket; 7 8 /* 9 * 基于TCP协议的Socket通信,实现用户登陆 10 * 服务器端 11 */ 12 public class Server { 13 public static void main(String[] args) { 14 try { 15 //1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口 16 ServerSocket serverSocket = new ServerSocket(8888); 17 //2.调用accept()方法开始监听,等待客户端的连接 18 System.out.println("***服务器即将启动,等待客户端的连接***"); 19 Socket socket = serverSocket.accept(); 20 //3.获取输入流,并读取客户端信息 21 InputStream is = socket.getInputStream();//字节输入流 22 InputStreamReader isr = new InputStreamReader(is);//将字节流转换为字符流 23 BufferedReader br = new BufferedReader(isr);//为输入流添加缓冲 24 String info = null; 25 while((info=br.readLine())!=null) {//循环读取客户端的信息 26 System.out.println("我是服务器,客户端说:" + info); 27 } 28 socket.shutdownInput();//关闭输入流 29 30 //4.关闭资源 31 br.close(); 32 isr.close(); 33 is.close(); 34 socket.close(); 35 serverSocket.close(); 36 } catch (IOException e) { 37 // TODO Auto-generated catch block 38 e.printStackTrace(); 39 } 40 41 } 42 43 }
客户端:
1.创建Socket对象,指明需要连接的服务器的地址和端口号
2.连接建立后,通过输出流向服务器发送请求信息
3.通过输入流获取服务器响应的信息
4.关闭相应资源
1 import java.io.IOException; 2 import java.io.OutputStream; 3 import java.io.PrintWriter; 4 import java.net.Socket; 5 import java.net.UnknownHostException; 6 7 /* 8 * 客户端 9 */ 10 public class Client { 11 public static void main(String[] args) { 12 try { 13 //1.创建客户端Socket,指定服务器地址和端口 14 Socket socket = new Socket("localhost",8888); 15 //2.获取输出流,向服务器端发送信息 16 OutputStream os = socket.getOutputStream();//字节输出流 17 PrintWriter pw = new PrintWriter(os); 18 pw.write("用户名:admin;密码:123"); 19 pw.flush(); 20 socket.shutdownOutput();//关闭输出流 21 22 //3.关闭资源 23 pw.close(); 24 os.close(); 25 socket.close(); 26 } catch (UnknownHostException e) { 27 e.printStackTrace(); 28 } catch (IOException e) { 29 e.printStackTrace(); 30 } 31 } 32 }
三、完善用户登陆之服务器响应客户端
服务端:
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStream; 4 import java.io.InputStreamReader; 5 import java.io.OutputStream; 6 import java.io.PrintWriter; 7 import java.net.ServerSocket; 8 import java.net.Socket; 9 10 /* 11 * 基于TCP协议的Socket通信,实现用户登陆 12 * 服务器端(需要早于客户端启动) 13 */ 14 public class Server { 15 public static void main(String[] args) { 16 try { 17 //1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口 18 ServerSocket serverSocket = new ServerSocket(8888); 19 //2.调用accept()方法开始监听,等待客户端的连接 20 System.out.println("***服务器即将启动,等待客户端的连接***"); 21 Socket socket = serverSocket.accept(); 22 //3.获取输入流,并读取客户端信息 23 InputStream is = socket.getInputStream();//字节输入流 24 InputStreamReader isr = new InputStreamReader(is);//将字节流转换为字符流 25 BufferedReader br = new BufferedReader(isr);//为输入流添加缓冲 26 String info = null; 27 while((info=br.readLine())!=null) {//循环读取客户端的信息 28 System.out.println("我是服务器,客户端说:" + info); 29 } 30 socket.shutdownInput();//关闭输入流 31 32 //4.获取输出流,响应客户端的请求 33 OutputStream os = socket.getOutputStream(); 34 PrintWriter pw = new PrintWriter(os);//包装为打印流 35 pw.write("欢迎您!"); 36 pw.flush();//调用flush()方法将缓冲输出 37 38 //5.关闭资源 39 pw.close(); 40 os.close(); 41 br.close(); 42 isr.close(); 43 is.close(); 44 socket.close(); 45 serverSocket.close(); 46 } catch (IOException e) { 47 // TODO Auto-generated catch block 48 e.printStackTrace(); 49 } 50 51 } 52 53 }
客户端:
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStream; 4 import java.io.InputStreamReader; 5 import java.io.OutputStream; 6 import java.io.PrintWriter; 7 import java.net.ServerSocket; 8 import java.net.Socket; 9 10 /* 11 * 基于TCP协议的Socket通信,实现用户登陆 12 * 服务器端(需要早于客户端启动) 13 */ 14 public class Server { 15 public static void main(String[] args) { 16 try { 17 //1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口 18 ServerSocket serverSocket = new ServerSocket(8888); 19 //2.调用accept()方法开始监听,等待客户端的连接 20 System.out.println("***服务器即将启动,等待客户端的连接***"); 21 Socket socket = serverSocket.accept(); 22 //3.获取输入流,并读取客户端信息 23 InputStream is = socket.getInputStream();//字节输入流 24 InputStreamReader isr = new InputStreamReader(is);//将字节流转换为字符流 25 BufferedReader br = new BufferedReader(isr);//为输入流添加缓冲 26 String info = null; 27 while((info=br.readLine())!=null) {//循环读取客户端的信息 28 System.out.println("我是服务器,客户端说:" + info); 29 } 30 socket.shutdownInput();//关闭输入流 31 32 //4.获取输出流,响应客户端的请求 33 OutputStream os = socket.getOutputStream(); 34 PrintWriter pw = new PrintWriter(os);//包装为打印流 35 pw.write("欢迎您!"); 36 pw.flush();//调用flush()方法将缓冲输出 37 38 //5.关闭资源 39 pw.close(); 40 os.close(); 41 br.close(); 42 isr.close(); 43 is.close(); 44 socket.close(); 45 serverSocket.close(); 46 } catch (IOException e) { 47 // TODO Auto-generated catch block 48 e.printStackTrace(); 49 } 50 51 } 52 53 }
四、使用多线程实现多客户端的通信
应用多线程来实现服务器与多客户端之间的通信
基本步骤:
1.服务器端创建ServerSocket,循环调用accept()等待客户端连接
2.客户端创建一个socket并请求和服务器端连接
3.服务器端接受客户端请求,创建socket与该客户建立专线连接
4.建立连接的两个socket在一个单独的线程上对话
5.服务器端继续等待新的连接
服务器线程处理类:
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStream; 4 import java.io.InputStreamReader; 5 import java.io.OutputStream; 6 import java.io.PrintWriter; 7 import java.net.Socket; 8 9 /* 10 * 服务器线程处理类 11 */ 12 public class ServerThread extends Thread { 13 // 和本线程相关的Socket 14 Socket socket = null; 15 16 public ServerThread(Socket socket) { 17 this.socket = socket; 18 } 19 20 //线程执行的操作,响应客户端的请求 21 public void run(){ 22 InputStream is=null; 23 InputStreamReader isr=null; 24 BufferedReader br=null; 25 OutputStream os=null; 26 PrintWriter pw=null; 27 try { 28 //获取输入流,并读取客户端信息 29 is = socket.getInputStream(); 30 isr = new InputStreamReader(is); 31 br = new BufferedReader(isr); 32 String info=null; 33 while((info=br.readLine())!=null){//循环读取客户端的信息 34 System.out.println("我是服务器,客户端说:"+info); 35 } 36 socket.shutdownInput();//关闭输入流 37 //获取输出流,响应客户端的请求 38 os = socket.getOutputStream(); 39 pw = new PrintWriter(os); 40 pw.write("欢迎您!"); 41 pw.flush();//调用flush()方法将缓冲输出 42 } catch (IOException e) { 43 e.printStackTrace(); 44 }finally{ 45 //关闭资源 46 try { 47 if(pw!=null) 48 pw.close(); 49 if(os!=null) 50 os.close(); 51 if(br!=null) 52 br.close(); 53 if(isr!=null) 54 isr.close(); 55 if(is!=null) 56 is.close(); 57 if(socket!=null) 58 socket.close(); 59 } catch (IOException e) { 60 e.printStackTrace(); 61 } 62 } 63 } 64 }
修改服务器端:
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStream; 4 import java.io.InputStreamReader; 5 import java.io.OutputStream; 6 import java.io.PrintWriter; 7 import java.net.InetAddress; 8 import java.net.ServerSocket; 9 import java.net.Socket; 10 11 /* 12 * 基于TCP协议的Socket通信,实现用户登陆 13 * 服务器端(需要早于客户端启动) 14 */ 15 public class Server { 16 public static void main(String[] args) { 17 try { 18 //1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口 19 ServerSocket serverSocket = new ServerSocket(8888); 20 21 Socket socket = null; 22 //记录客户端的数量 23 int count = 0; 24 System.out.println("***服务器即将启动,等待客户端的连接***"); 25 //循环监听等待客户端的连接 26 while (true) { 27 //2.调用accept()方法开始监听,等待客户端的连接 28 socket = serverSocket.accept(); 29 //创建一个新的线程 30 ServerThread serverThread = new ServerThread(socket); 31 //启动线程 32 serverThread.start(); 33 34 count++;//统计客户端的数量 35 System.out.println("输出客户端的数量:" + count); 36 InetAddress address = socket.getInetAddress(); 37 System.out.println("当前客户端的IP:" + address.getHostAddress()); 38 } 39 40 41 42 43 /* 44 //3.获取输入流,并读取客户端信息 45 InputStream is = socket.getInputStream();//字节输入流 46 InputStreamReader isr = new InputStreamReader(is);//将字节流转换为字符流 47 BufferedReader br = new BufferedReader(isr);//为输入流添加缓冲 48 String info = null; 49 while((info=br.readLine())!=null) {//循环读取客户端的信息 50 System.out.println("我是服务器,客户端说:" + info); 51 } 52 socket.shutdownInput();//关闭输入流 53 54 //4.获取输出流,响应客户端的请求 55 OutputStream os = socket.getOutputStream(); 56 PrintWriter pw = new PrintWriter(os);//包装为打印流 57 pw.write("欢迎您!"); 58 pw.flush();//调用flush()方法将缓冲输出 59 60 //5.关闭资源 61 pw.close(); 62 os.close(); 63 br.close(); 64 isr.close(); 65 is.close(); 66 socket.close(); 67 */ 68 69 70 //serverSocket.close(); 71 72 } catch (IOException e) { 73 // TODO Auto-generated catch block 74 e.printStackTrace(); 75 } 76 77 } 78 79 }
修改客户端:
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStream; 4 import java.io.InputStreamReader; 5 import java.io.OutputStream; 6 import java.io.PrintWriter; 7 import java.net.Socket; 8 import java.net.UnknownHostException; 9 10 /* 11 * 客户端 12 */ 13 public class Client { 14 public static void main(String[] args) { 15 try { 16 //1.创建客户端Socket,指定服务器地址和端口 17 Socket socket = new Socket("localhost",8888); 18 //2.获取输出流,向服务器端发送信息 19 OutputStream os = socket.getOutputStream();//字节输出流 20 PrintWriter pw = new PrintWriter(os); 21 pw.write("用户名:admin;密码:123"); 22 pw.flush(); 23 socket.shutdownOutput();//关闭输出流 24 25 //3.获取输入流,并读取服务器端的响应信息 26 InputStream is = socket.getInputStream();//字节输入流 27 BufferedReader br = new BufferedReader( 28 new InputStreamReader(is));//将字节流转换为字符流,为输入流添加缓冲 29 String info = null; 30 while((info=br.readLine())!=null) {//循环读取客户端的信息 31 System.out.println("我是客户端,服务器说:" + info); 32 } 33 34 //4.关闭资源 35 br.close(); 36 is.close(); 37 pw.close(); 38 os.close(); 39 socket.close(); 40 } catch (UnknownHostException e) { 41 e.printStackTrace(); 42 } catch (IOException e) { 43 e.printStackTrace(); 44 } 45 } 46 }