TCP编程

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();   //刷新
            }
        }
    }
}
原文地址:https://www.cnblogs.com/HelloM/p/14149890.html