Socket编程之 TCP/IP协议实战

574 篇文章 4 订阅

1.客户端代码:

package com.jidongcloud.bean;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import java.io.*;
import java.net.*;

/**
 * ClassName:ChatClient
 * PackageName:com.jidongcloud.bean
 * Description: 传输层 TCP/IP协议实战
 *
 * @date:2020/4/20 10:31
 * @author:robin
 */

public class ChatClient {
    public  static    String  client() throws IOException {
        System.out.println("进入客户端");
        //创建TCP客户端
        byte[]addr={-64,-88,-108,2};
        InetAddress address = InetAddress.getByAddress(addr);
//        创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
        Socket socket = new Socket(address, 1234);
        //获取socket输出流对象
        OutputStreamWriter socketOut = new OutputStreamWriter(socket.getOutputStream());
        //获取socket输入流对象
        BufferedReader socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        //获取键盘输入流对象,读取数据
        BufferedReader keyBoardReader = new BufferedReader(new InputStreamReader(System.in));
        String line =null;
        System.out.println("(客户端)我说:");
        while((line=keyBoardReader.readLine()) !=null ){
            //把键盘输入的数据写到socket中,向服务器端发送请求数据。
            socketOut.write(line+"\n");
            //刷新
            socketOut.flush();
            //读取服务器端返回的数据
            line = socketReader.readLine();
            System.out.println("服务器:"+line);
            System.out.println("(客户端)我说:");
        }
        //用完socket就关闭socket
        socket.close();
               return "index";
    }
    public static void main(String[] args) throws IOException {
//          client();
        Socket socket=new Socket();
        //超时时间
        socket.setSoTimeout(3000);
        //本地连接   端口号要与服务器端端口号一致
        socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(),2000),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 {
        //1.构建基础数据输入流
        InputStream in = System.in;
        BufferedReader input=new BufferedReader(new InputStreamReader(in));


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

        //3.接收服务端的返回,得到socket输入流
        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("服务器返回除了 bye 之外的 其他信息:"+echo);
            }
        }while (flag);
        //资源释放
        socketPrintStream.close();
        SocketBufferedReader.close();
    }
}

2.服务端代码:

package com.jidongcloud.bean;

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

/**
 * ClassName:ChatServer
 * PackageName:com.jidongcloud.bean
 * Description:
 *
 * @date:2020/5/7 22:08
 * @author:robin
 */
public class ChatServer {
    public static void main(String[] args) throws IOException {
        ServerSocket server=new ServerSocket(2000);
        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.getPort());
            try {
                //1.得到打印流,用于数据输出;服务器回送数据使用。
                PrintStream socketOutput = new PrintStream(socket.getOutputStream());

                //2.输出之前先获取输入流,用于接收数据
                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 (IOException e) {
                System.out.println("连接异常断开");
            }finally {
                try {
                    //连接整体关闭
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("客户端已退出:"+socket.getInetAddress()+"p:"+socket.getPort());
        }
        //备注 : server 服务端一直开着就绪状态的,客户端失去连接。
    }
}

3.测试:先启动服务端代码,后启动客户端代码
在这里插入图片描述

在这里插入图片描述

4.客户端输入:
在这里插入图片描述
服务端接收:
在这里插入图片描述
总结:

TCP/IP协议是长连接的协议,http是无状态协议。(短连接,一次请求一次响应即断开连接。)

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

Socket API参考链接:
点击跳转

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值