TCP/IP 协议栈学习代码

时间:2021-05-26 10:31:47

直接使用socket

客户端

import java.io.*;
import java.net.Inet4Address;
import java.net.InetSocketAddress;
import java.net.Socket;

public class Client {
     public static void main(String[] args)throws IOException {
        Socket socket=new Socket();
        //超时时间
        socket.setSoTimeout(3000);
        //连接本地端口8080,超时时间2000ms
         socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(),8080),3000);
         System.out.println("已发起服务器连接并进入后续流程~");
         System.out.println("客户端信息:"+socket.getLocalAddress()+" P:"+socket.getLocalPort());
         System.out.println("服务端信息:"+socket.getInetAddress()+" P:"+socket.getPort());
         try{
             //发送接受数据
             todo(socket);
         }catch (Exception e){
             System.out.println("异常关闭");
         }
         socket.close();
         System.out.println("客户端已退出~");

    }
    private static  void todo(Socket client) throws IOException{
         //构建键盘输入流
        InputStream in=System.in;
        BufferedReader input=new BufferedReader(new InputStreamReader(in));

        //socket输出流,并转换为打印流
        OutputStream outputStream=client.getOutputStream();
        PrintStream socketPrintStream=new PrintStream(outputStream);

        //得到Socket输入流,并转换为BufferReader
        InputStream inputStream=client.getInputStream();
        BufferedReader socketBufferedReader=new BufferedReader(new InputStreamReader(inputStream));

        boolean flag=true;
        do {
            //键盘读取一行
            String str =input.readLine();

            //发送到服务器
            socketPrintStream.println(str);

            //从服务器读取一行
            String echo = socketBufferedReader.readLine();
            if ("bye".equalsIgnoreCase(echo)) {
                flag = false;
            }
            else
            {
                System.out.println(echo);
            }
        }
        while (flag);

        //资源释放
        socketPrintStream.close();
        socketBufferedReader.close();
    }
}

服务端

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket server=new ServerSocket(8080);


        System.out.println("服务器准备就绪~");
        System.out.println("服务器信息:"+server.getInetAddress()+" P:"+server.getLocalPort());


        for( ;;) {
            //等待客服端连接
            Socket client = server.accept();
            ClientHandler clientHandler = new ClientHandler(client);
            clientHandler.start();
        }
    }
    /*
    客户端消息处理
     */
    private  static class ClientHandler extends Thread{
        private Socket socket;
        private boolean flag=true;
        ClientHandler(Socket socket)
        {
            this.socket=socket;

        }

        @Override
        public void run() {
            super.run();
            System.out.println("新客户端连接:"+socket.getInetAddress()+" P:"+socket.getLocalPort());

            try{
                //得到打印流,用于数据输出;服务器回送数据
                PrintStream socketOutput=new PrintStream(socket.getOutputStream());
                //得到输入流,用于接受数据
                BufferedReader socketInput =new BufferedReader(new InputStreamReader(
                        socket.getInputStream()));
                do {
                    //客户端拿到一条数据
                    String str=socketInput.readLine();
                    if("bye".equalsIgnoreCase(str))
                    {
                        flag=false;
                        //回送
                        socketOutput.println("bye");
                    }
                    else
                    {
                        System.out.println(str);
                        socketOutput.println("回送:"+str.length());
                    }
                }while(flag);
                socketInput.close();
                socketOutput.close();
            }catch (Exception e) {
                System.out.println("连接异常断开");
            }finally {
                //连接关闭
                try {
                socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("客户端已关闭"+socket.getInetAddress()+" P:"+socket.getLocalPort());
        }
    }
}

使用UDP

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

/*
UDP提供者,用于提供服务
 */
public class UDPProvider {
    public static void main(String[] args) throws IOException {
        System.out.println("UDPProvider Started.");
        //作为接收者,指定一个端口用于数据接收
        DatagramSocket ds=new DatagramSocket(20000);

        //构建接收实体
        final byte[] buf=new byte[512];

        DatagramPacket receivePack=new DatagramPacket(buf,buf.length);

        //接收
        ds.receive(receivePack);

        //打印接收到的信息与发送者的信息
        //发送者的IP地址
        String ip=receivePack.getAddress().getHostAddress();
        int port=receivePack.getPort();
        int dataLen=receivePack.getLength();
        String data=new String(receivePack.getData(),0,dataLen);
        System.out.println("UDPProvider receive form IP: +ip" +
                "\tPort"+port +"\tData:"+data);
        //构建一份回送数据
        String responseData="Receive data with len"+dataLen;
        byte[] responseDataBytes=responseData.getBytes();
        //直接根据发送者构建一份回送信息
        DatagramPacket respnsePacket= new DatagramPacket(responseDataBytes,
                responseDataBytes.length,
                receivePack.getAddress(),
                receivePack.getPort()
        );
        ds.send(respnsePacket);
        //完成
        System.out.println("UDPProvider Finished.");
        ds.close();

    }
}

 

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;


/*
UDP提供者,用于提供服务
 */
public class UDPSearcher {
    public static void main(String[] args) throws IOException {
        System.out.println("UDPSearcher Started.");
        //作为搜素者,无需指定端口
        DatagramSocket ds=new DatagramSocket();
        //构建一份请求数据
        String resquestData="Hello world!";
        byte[] resquestDataBytes=resquestData.getBytes();
        DatagramPacket resquestPacket= new DatagramPacket(resquestDataBytes,
                resquestDataBytes.length
        );
        //本机20000端口
        resquestPacket.setAddress(InetAddress.getLocalHost());
        resquestPacket.setPort(20000);
        //发送
        ds.send(resquestPacket);
        //构建接收实体
        final byte[] buf=new byte[512];

        DatagramPacket receivePack=new DatagramPacket(buf,buf.length);

        //接收
        ds.receive(receivePack);

        //打印接收到的信息与发送者的信息
        //发送者的IP地址
        String ip=receivePack.getAddress().getHostAddress();
        int port=receivePack.getPort();
        int dataLen=receivePack.getLength();
        String data=new String(receivePack.getData(),0,dataLen);
        System.out.println("UDPSearcher receive form IP: +ip" +
                "\tport"+"Port:"+port +"\tdata:"+data);

        //完成
        System.out.println("UDPSearcher Finished.");
        ds.close();

    }
}

使用SN

public class MessageCreator {
    private static final String SN_HEADER="收到暗号,我是(SN):";
    private static final String PORT_HEADER="这是暗号,请回电口(Port)";

    public static String buildWithPort(int port){
        return PORT_HEADER+port;
    }
    public static int parsePort(String data){
        if(data.startsWith(PORT_HEADER)){
            return Integer.parseInt(data.substring(PORT_HEADER.length()));
        }
        return -1;
    }

    public static String buildWithSn(String sn){
        return SN_HEADER+sn;
    }
    public static String parseSN(String data){
        if(data.startsWith(SN_HEADER)){
            return data.substring(SN_HEADER.length());
        }
        return null;
    }
}