Socket请求_JAVA实现TCP通信

1、服务器端socket

创建ServerSocket对象,绑定监听端口。
通过accept()方法监听客户端请求。
连接建立后,通过输入流读取客户端发送的请求信息。
通过输出流向客户端发送响应信息。
关闭响应的资源。

2、客户端socket

创建Socket对象,指明需要连接的服务器的地址和端口号。
连接建立后,通过输出流向服务器发送请求信息。
通过输入流获取服务器响应的信息。
关闭相应资源。

3、多线程实现服务器与多客户端之间通信步骤

服务器端创建ServerSocket,循环调用accept()等待客户端连接。
客户端创建一个socket并请求和服务器端连接。
服务器端接受客户端请求,创建socket与该客户建立专线连接。
建立连接的两个socket在一个单独的线程上对话。
服务器端继续等待新的连接。

4、服务端code
package socker;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Description: Socket 服务端,用于模拟测试使用
 *
 * 用线程池的方式,算是一种成熟的方式。可以应用在生产中。
 * ServerSocket有以下3个属性。
 *
 * SO_TIMEOUT:表示等待客户连接的超时时间。一般不设置,会持续等待。
 * SO_REUSEADDR:表示是否允许重用服务器所绑定的地址。一般不设置
 * SO_RCVBUF:表示接收数据的缓冲区的大小。一般不设置,用系统默认就可以了。
 *
 * @Author: LT
 * @CreateDate: 2019/10/21 14:40
 * @Version: 1.0.0
 */

public class SocketServerDemo {

    public static void main(String args[]) throws Exception {
        // 监听指定的端口
        ServerSocket server = new ServerSocket(8888);
        // server将一直等待连接的到来
        System.out.println("server将一直等待连接的到来");

        //如果使用多线程,那就需要线程池,防止并发过高时创建过多线程耗尽资源
        ExecutorService threadPool = Executors.newFixedThreadPool(80);

        while (true) {
            Socket socket = server.accept();

            Runnable runnable = () -> {
                try {
                    // 建立好连接后,从socket中获取输入流,并建立缓冲区进行读取
                    InputStream inputStream = socket.getInputStream();
                    byte[] bytes = new byte[1024];
                    int len;
                    StringBuilder sb = new StringBuilder();
                    while ((len = inputStream.read(bytes)) != -1) {
                        // 注意指定编码格式,发送方和接收方一定要统一,建议使用UTF-8
                        sb.append(new String(bytes, 0, len, "UTF-8"));
                    }
                    System.out.println("get message from client: " + sb);
                    OutputStream out=socket.getOutputStream();

                    String resp = "我是服务器";
                    out.write(resp.getBytes());
                    inputStream.close();
                    socket.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            };
            threadPool.submit(runnable);
        }
    }
}
5、客户端code
package socker;

/**
 * @Description: java类作用描述
 * @Author: LT
 * @CreateDate: 2019/10/21 13:59
 * @Version: 1.0.0
 */

import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;


public class Client {

    /**
     * Socket客户端
     */
    public static void main(String[] args) {
        String requestMsg = "client xml or json 数据";
        String address = "localhost";
        int port = 8888;
        send(address,port,requestMsg);

    }

    /**
     * Socket 客户端请求
     *
     * @param address ip地址
     * @param port 端口
     * @param requestMsg 请求内容
     */
    public static void send(String address,int port, String requestMsg) {

        try {
            //创建Socket对象
            Socket socket=new Socket(address,port);
            /**
             * 根据输入输出流和服务端连接
             * 1)获取一个输出流,向服务端发送信息
             * 2)将输出流包装成打印流
             * 3)关闭输出流
             */
            OutputStream outputStream=socket.getOutputStream();
            PrintWriter printWriter=new PrintWriter(outputStream);
            printWriter.print(requestMsg);
            printWriter.flush();
            socket.shutdownOutput();

            //获取一个输入流,接收服务端的信息
            InputStream inputStream=socket.getInputStream();
            //包装成字符流,提高效率
            InputStreamReader inputStreamReader=new InputStreamReader(inputStream);
            //缓冲区
            BufferedReader bufferedReader=new BufferedReader(inputStreamReader);
            StringBuffer sb = new StringBuffer();
            //临时变量
            String temp=null;
            while((temp=bufferedReader.readLine())!=null){
                sb.append(temp).append("\n");
            }
            System.out.println("客户端接收服务端发送信息:"+sb.toString());

            //关闭相对应的资源
            bufferedReader.close();
            inputStream.close();
            printWriter.close();
            outputStream.close();
            socket.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

参考文章:
java面试-线程池

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值