TCP通信
Tcp通信的总体流程,控制台字符输入流读取内容,数据输出流将信息打包写入发送给服务端。服务端数据输入流接收读取信息,使用数据输出流,将响应信息写出发送给客户端。客户端使用数据输入流,读取服务器发送的信息,显示到控制台上。
客户端
客户端发送信息,接收信息使用两个线程进行运作。
package com.demo02.demo01.tcp.demo02; import java.io.IOException; import java.io.InputStream; import java.net.Socket; import java.net.UnknownHostException; /** * 三次握手请求 * 客户端发送一次请求 * 服务器回送 * 客户端接收请求,显示信息 * * * 创建客户端: 发送数据+接受数据 * 写出数据:输出流 * 读取数据:输入流 * * 输入流与输出流 在同一个线程内 应该独立处理 彼此独立 * @author Administrator * */ public class Client { public static void main(String[] args) throws IOException { //建立连接 Socket client = new Socket("localhost", 9999); //收发消息是同步进行的 new Thread(new Send(client)).start(); //一条路径 发消息 new Thread(new Receive(client)).start(); //一条路径 收消息 } }
发送信息线程
package com.demo02.demo01.tcp.demo02; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; //发送数据 线程 public class Send implements Runnable { //控制台输入流 private BufferedReader console; //管道输出流 private DataOutputStream dos; //控制线程 private boolean isRunning = true; public Send() { //输入流拿到控制台的数据 console = new BufferedReader(new InputStreamReader(System.in)); } public Send(Socket client) { this(); try { //输出流 是向服务器发信息的 dos = new DataOutputStream(client.getOutputStream()); }catch(IOException e) { isRunning = false; CloseUtil.closeAll(dos, console); } } //1、从控制台接收数据 private String getMsgFromConsole() { try { //返回读取的控制台信息 return console.readLine(); }catch(IOException e) { } return ""; } /** * 1. 从控制台接收数据 * 2. 发送数据 */ public void send() { //拿到console读取的信息流 String msg = getMsgFromConsole(); try { //判空 if(null!=msg&& !msg.equals("")) { //写入到输出流 目的地client=客户端 dos.writeUTF(msg); dos.flush(); //强制刷新 } }catch(IOException e) { isRunning = false; CloseUtil.closeAll(dos, console); } } //线程运行 @Override public void run() { //线程体 while(isRunning) { //如果true 发送消息 send(); } } }
接收线程
package com.demo02.demo01.tcp.demo02; import java.io.DataInputStream; import java.io.IOException; import java.net.Socket; public class Receive implements Runnable{ //输入流 private DataInputStream dis; //线程表示 private boolean isRunning = true; public Receive() { } public Receive(Socket client) { try { //拿到客户端收到的服务器信息 dis = new DataInputStream(client.getInputStream()); }catch(IOException e) { e.printStackTrace(); isRunning = false; CloseUtil.closeAll(dis); } } /** * 接收数据 */ public String receive() { String msg = ""; try { // msg = dis.readUTF(); //读取来自服务器的消息 System.out.println("client-receive:" + msg); }catch(IOException e) { e.printStackTrace(); isRunning = false; CloseUtil.closeAll(dis); } return msg; } @Override public void run() { //线程体 while(isRunning) { System.out.println(receive()); //线程运行接收消息 } } }
关闭流工具
package com.demo02.demo01.tcp.demo02; import java.io.Closeable; //关闭流的方法 public class CloseUtil { public static void closeAll(Closeable... io) { for(Closeable temp: io) { try { if(null != temp) { temp.close(); //关闭 } }catch(Exception e) { } } } }
服务端
package com.demo02.demo01.tcp.demo02; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; /** * 创建服务器 * 写出数据:输出流 * 读取数据:输入流 * @author Administrator * */ public class Server { public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(9999); //localhost:9999 while(true) { Socket client = server.accept(); //阻塞式接收信息 //写出数据 //输入流 读取客户端发送过来的信息 拿过来 DataInputStream dis = new DataInputStream(client.getInputStream()); //输出流 写出到客户端 送出去 DataOutputStream dos = new DataOutputStream(client.getOutputStream()); while(true) { String msg = dis.readUTF(); System.out.println(msg); //输出流 dos.writeUTF("服务器-->" + msg); //想客户端发送 dos.flush(); //刷新 } } } }