Java多线程TCP客户端与服务器间使用Socket通信

Socket是一个有效的网络通信的工具,下面这个简单例子给大家演示一下如何使用Socket来做服务器与客户端之间的通信 客户端代码

/** * @author Jian * 客户端 */ public class Client { public static void main(String[] args) { try { //1.创建客户端Socket,指定服务器地址和端口,本机也可以为localhost Socket socket= new Socket("127.0.0.1", 1344); //2.获取输出流,向服务器端发送登录信息 OutputStream os = socket.getOutputStream(); //字节输出流 *//** *可以装饰为打印流,也可以采用下装饰为字符输出流,使用缓冲来写入 *PrintWriter pw = new PrintWriter(os); //输出流包装为打印流 *//* OutputStreamWriter osw = new OutputStreamWriter(os); BufferedWriter pw = new BufferedWriter(osw); pw.write("用户名:admin; 密码:123"); pw.flush(); //调用flush()刷新缓存 //关闭输出流 socket.shutdownOutput(); //3.获取输入流,读取服务器端相应信息 InputStream is = socket.getInputStream(); InputStreamReader isr = new InputStreamReader(is); //字节流转换为字符流 BufferedReader br = new BufferedReader(isr); //为输入流添加缓冲 String info = null; while((info=br.readLine())!=null){//循环读取服务器端响应信息 System.out.println("服务器端信息:"+info); } //4.关闭相关资源 br.close(); isr.close(); is.close(); pw.close(); osw.close(); os.close(); socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }

服务器端代码
/** * @author Jian * 基于TCP协议的Socket通信,实现用户登录 * 服务器端 */ public class Server { /*public static void main(String[] args) { try { //1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口 ServerSocket serverSocket = new ServerSocket(1344); //2.调用accept()方法,等待客户端的连接 System.out.println("-----服务器即将启动,等待客户端连接"); Socket socket = serverSocket.accept(); //阻塞式 //3.获取输入流,并读取客户端信息 InputStream is = socket.getInputStream(); //字节输入流 InputStreamReader isr = new InputStreamReader(is); //字节流转换为字符流 BufferedReader br = new BufferedReader(isr); //为输入流添加缓冲 String info = null; while((info=br.readLine())!=null){//循环读取 System.out.println("服务器收到的客户端数据"+info); } //socket.shutdownInput(); //关闭输入流 //4.获取输出流,响应客户端的请求 OutputStream os = socket.getOutputStream(); PrintWriter pw = new PrintWriter(os); pw.write("Welcome!"); pw.flush(); //刷新缓存 //5.关闭相关资源 pw.close(); os.close(); br.close(); isr.close(); is.close(); socket.close(); serverSocket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }*/

在客户端的代码中,发送完数据后需要调用shutdownOutput()来告诉服务器端已经发送完毕,这样会使得接下来再利用输出流来向服务器发送信息,所以我们可以将代码稍加修改 服务器端
DataInputStream dis = new DataInputStream(is); int flag = 0; while(true){//循环读取 flag = br.read(); System.out.println(flag); if(flag==1){ String data = https://www.it610.com/article/dis.readUTF(); System.out.println(data); } break; }

客户端
DataOutputStream dos = new DataOutputStream(os); pw.write(1); pw.flush(); dos.writeUTF(("用户名:admin; 密码:123")); dos.flush(); //调用flush()刷新缓存 //关闭输出流 //socket.shutdownOutput();

这里我们可以先约定好通信协议,传数字代表的含义,然后可以在服务器端的监听中调用别的方法,使用DataInputStream的readUTF()方法可以读取整段文字,你可以自行设计方法,来避免shutdownIn/Output()后造成无法读写的问题。 尝试一下多线程下的Socket通信
【Java多线程TCP客户端与服务器间使用Socket通信】客户端没有什么变化,只要让Server保持死循环监听,每有一个客户端连接进来,就开启一个线程,并在这个线程里与客户端进行通信,具体代码如下:
服务器端
//1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口 ServerSocket serverSocket = new ServerSocket(1344); //2.调用accept()方法,等待客户端的连接 System.out.println("-----服务器即将启动,等待客户端连接"); Socket socket = null; //記錄客戶端數量 int count = 0; while(true){ 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()); } //serverSocket.close();

线程类
/** * @author Jian * 服务器端线程处理类 */ public class ServerThread extends Thread{ //和本线程相关的Socket Socket socket = null; public ServerThread(Socket socket) { this.socket = socket; } //线程的操作,响应客户端请求 public void run(){ InputStreamReader isr=null; InputStream is=null; BufferedReader br=null; OutputStream os=null; PrintWriter pw=null; //3.获取输入流,并读取客户端信息 try { is = socket.getInputStream(); isr = new InputStreamReader(is); //字节流转换为字符流 br = new BufferedReader(isr); //为输入流添加缓冲 String info = null; while((info=br.readLine())!=null){//循环读取 System.out.println("服务器收到的客户端数据"+info); } socket.shutdownInput(); //关闭输入流 //4.获取输出流,响应客户端的请求 os = socket.getOutputStream(); pw = new PrintWriter(os); pw.write("Welcome!"); pw.flush(); //刷新缓存} catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ //5.关闭相关资源 try { if(pw!=null) pw.close(); if(os!=null) os.close(); if(br!=null) br.close(); if(isr!=null) isr.close(); if(is!=null) is.close(); if(socket!=null) socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }} }

这里列举的只是基本的用法,希望能对你有所帮助,大家还需要多加练习,加油!

    推荐阅读