Socket实现服务器与客户端的交互

连接过程:
(1)服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。
(2)客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
(3)连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
socket连接过程图解

demo:
Client客户端:
import java.io.*; import java.net.Socket; import java.util.Scanner; /** * Created by Administrator on 2017/6/27. * 客户端 */ public class Client { public static void main(String[] args) { Socket socket = null; OutputStream os = null; //PrintWriter pw = null; Scanner scanner = null; InputStream is = null; BufferedReader br = null; try { //创建客户端Socket,指定服务器地址和端口 socket = new Socket("localhost", 8888); //获取输出流,向服务器发送信息 os = socket.getOutputStream();//字节输出流 // pw = new PrintWriter(os);//将输出流包装为打印流 // pw.write("用户名:cw,密码:0813"); // pw.flush(); System.out.println("客户端,请输入多个字符:"); scanner = new Scanner(System.in); String str = scanner.next(); os.write(str.getBytes()); os.flush(); //socket.shutdownInput(); //获取输入流,并读取服务器端的响应信息 // is = socket.getInputStream(); // br = new BufferedReader(new InputStreamReader(is)); // String info = null; // while ((info = br.readLine()) != null) { // System.out.println("服务器:" + info); // info=br.readLine(); // } } catch (Exception e) { e.printStackTrace(); } finally { if (socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } if (os != null) { try { os.close(); } catch (IOException e) { e.printStackTrace(); } } if (scanner != null) { scanner.close(); } /* if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } }*/ } } }
Server服务器端:
import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; /** * Created by Administrator on 2017/6/27. * 基于TCP协议的Socket通信,实现用户登陆 * 服务器端 */ public class Server { public static void main(String[] args) { try{ //创建一个服务器端Socket,指定并监听端口 ServerSocket serverSocket=new ServerSocket(8888); Socket socket=null; int count =0; System.out.println("*****服务器即将启动,等待客户端的连接*****"); //循环监听等待客户端的连接 while(true){ //调用accept()方法开始监听,等待客户端的连接 socket = serverSocket.accept(); //创建一个线程 ServerThread serverThread=new ServerThread(socket); //启动线程 serverThread.start(); count++; System.out.println("客户端的数量:"+count); InetAddress address = socket.getInetAddress(); System.out.println("当前客户端的IP:"+address.getHostAddress()); } }catch (Exception e){ e.printStackTrace(); } } }
ServerThread线程:
连接过程: 根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。 (1)服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。 (2)客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。 (3)连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。 socket连接过程图解 demo: Client客户端: import java.io.*; import java.net.Socket; import java.util.Scanner; /** * Created by Administrator on 2017/6/27. * 客户端 */ public class Client { public static void main(String[] args) { Socket socket = null; OutputStream os = null; //PrintWriter pw = null; Scanner scanner = null; InputStream is = null; BufferedReader br = null; try { //创建客户端Socket,指定服务器地址和端口 socket = new Socket("localhost", 8888); //获取输出流,向服务器发送信息 os = socket.getOutputStream();//字节输出流 // pw = new PrintWriter(os);//将输出流包装为打印流 // pw.write("用户名:cw,密码:0813"); // pw.flush(); System.out.println("客户端,请输入多个字符:"); scanner = new Scanner(System.in); String str = scanner.next(); os.write(str.getBytes()); os.flush(); //socket.shutdownInput(); //获取输入流,并读取服务器端的响应信息 // is = socket.getInputStream(); // br = new BufferedReader(new InputStreamReader(is)); // String info = null; // while ((info = br.readLine()) != null) { // System.out.println("服务器:" + info); // info=br.readLine(); // } } catch (Exception e) { e.printStackTrace(); } finally { if (socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } if (os != null) { try { os.close(); } catch (IOException e) { e.printStackTrace(); } } if (scanner != null) { scanner.close(); } /* if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } }*/ } } } Server服务器端: import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; /** * Created by Administrator on 2017/6/27. * 基于TCP协议的Socket通信,实现用户登陆 * 服务器端 */ public class Server { public static void main(String[] args) { try{ //创建一个服务器端Socket,指定并监听端口 ServerSocket serverSocket=new ServerSocket(8888); Socket socket=null; int count =0; System.out.println("*****服务器即将启动,等待客户端的连接*****"); //循环监听等待客户端的连接 while(true){ //调用accept()方法开始监听,等待客户端的连接 socket = serverSocket.accept(); //创建一个线程 ServerThread serverThread=new ServerThread(socket); //启动线程 serverThread.start(); count++; System.out.println("客户端的数量:"+count); InetAddress address = socket.getInetAddress(); System.out.println("当前客户端的IP:"+address.getHostAddress()); } }catch (Exception e){ e.printStackTrace(); } } } ServerThread线程: import java.io.*; import java.net.Socket; import java.util.Scanner; /** * Created by Administrator on 2017/6/27. * 服务器线程处理类 */ public class ServerThread extends Thread { //和本线程相关的Socket Socket socket = null; public ServerThread(Socket socket) { this.socket = socket; } //线程执行的操作,响应客户端的请求2 @Override public void run() { InputStream is = null; InputStreamReader isr = null; BufferedReader br = null; OutputStream os = null; //PrintWriter pw = null; Scanner scanner = null; try { System.out.println("*****线程****"); //获取输入流,并读取客户端信息 is = socket.getInputStream(); isr = new InputStreamReader(is); br = new BufferedReader(isr); String info = null; while ((info = br.readLine()) != null) {//循环读取客户端信息 System.out.println("来自客户端:" + info); br.readLine(); } // socket.shutdownInput(); //socket.shutdownInput(); //获取输出流,响应服务端的请求 os = socket.getOutputStream(); System.out.println("服务器,请输入多个字符:"); scanner = new Scanner(System.in); String str = scanner.next(); os.write(str.getBytes()); // os.flush(); // pw = new PrintWriter(os); //pw.write("elcome!"); // pw.flush(); } catch (Exception e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } if (isr != null) { try { isr.close(); } catch (IOException e) { e.printStackTrace(); } } if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (os != null) { try { os.close(); } catch (IOException e) { e.printStackTrace(); } } if (scanner != null) { scanner.close(); } if (socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)