欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

使用Java实现基于TCP协议的网络通信

程序员文章站 2022-06-29 21:18:06
...

TCP/IP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket,从而在通信的两端之间形成网络虚拟链路。一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信。Java对基于TCP协议的网络通信提供了良好的封装,Java使用Socket对象来代表两端的通信端口,并通过产生IO流来进行网络通信。
两个实体通信示意图
使用Java实现基于TCP协议的网络通信
Java中能接收其他通信实体连接请求的类是ServerSocket,ServerSocket对象用于监听来自客户端的Socket连接,如果没有连接,它将一直处于等待状态。ServerSocket包含一个监听来自客户端连接请求的方法。

  • Socket accept():如果接收到一个客户端Socket的连接请求,该方法讲返回一个客户端Socket对应的Socket;否则该方法将一直处于等待状态,线程也被阻塞。
    创建ServerSocket对象,有以下几个构造器:

  • ServerSocket(int port):用指定的端口port来创建一个对象。该端口应该有一个有效的端口值,在0-65535之间。

  • ServerSocket(int port,int backlog):增加一个用来改变连接队列长度的参数backlog。

  • ServerSocket(int port,int backlog,InetAddress localAddr):在机器存在多个IP地址的情况下,允许通过localAddr参数来指定将ServerSocket绑定到指定的IP地址。
    使用Socket进行通信:
    客户端通常可以使用Socket的构造器来连接到指定服务器,Socket通常使用如下两个构造器:

  • Socket(InetAddress/String remoteAddress,int port):创建连接到指定远程主机、远程端口的Socket,并没有指定本地地址、本地端口,默认使用本地主机的默认IP地址,默认使用系统动态分配的端口。

  • Socket(InetAddress/String remoteAddress,int port,InetAddress localAddr,int localPort):创建连接到指定远程主机、远程端口的Socket,并指定本机IP地址和本地端口,适用于本地主机有多个IP地址的情形。
    建立Server端:

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

public class TCPServer {
    private int port = 12345;//定义端口号
    private ServerSocket socket;//定义ServerSocket

    public TCPServer() {//构造器:创建ServerSocket对象
        try {
            socket = new ServerSocket(port);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //启动服务器类
    public void startServer() {
        try {
            while (true) {
                //让服务器一直监听是否有新的客户请求连接
                Socket clientSocket = socket.accept();
                //建立通信:获取字节流
                InputStream inputStream = clientSocket.getInputStream();//输入流
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                OutputStream outputStream = clientSocket.getOutputStream();//输出流
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream));
                while (true) {
                    String s = null;
                    s = reader.readLine();
                    System.out.println("收到的消息为:" + s);
                    if (s.equals("exit")) {
                        break;
                    }

                    //给客户端回复消息
                    String str = "I receive your msg\n";//加回车把消息刷新出缓冲区
                    writer.write(str);
                    writer.flush();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new TCPServer().startServer();
    }
}

建立Client端:

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class TCPClient {
    private int port = 12345;//连接进程的端口号
    private String IP = "127.0.0.1";//服务器的IP地址
    private Socket clientSocket;
    private Scanner scanner;

    public TCPClient(){
        try {
            scanner = new Scanner(System.in);
            clientSocket = new Socket(IP,port);//创建socket对象
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void startClient(){
        OutputStream outputStream = null;
        BufferedWriter writer = null;
        InputStream inputStream = null;
        BufferedReader reader = null;
        try {
            outputStream = clientSocket.getOutputStream();
            writer = new BufferedWriter(new OutputStreamWriter(outputStream));
            inputStream = clientSocket.getInputStream();//输入流
            reader = new BufferedReader(new InputStreamReader(inputStream));
            while(true){
                String s = scanner.nextLine();
                writer.write(s);
                writer.write("\n");
                writer.flush();

                //结束通信:客户端输入exit
                if(s.equals("exit")){
                    break;
                }

                //就收服务端信息
                String msg = reader.readLine();
                System.out.println("收到服务器消息:"+msg);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭资源
            try {
                outputStream.close();
                inputStream.close();
                reader.close();
                writer.close();
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    public static void main(String[] args) {
        TCPClient client = new TCPClient();
        client.startClient();
    }

}

应用多线程
新建一个ServerHandler类:(也就是将通信部分的代码用多线程的方式实现)

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

public class ServerHandler implements Runnable{
    private Socket clientSocket;

    public ServerHandler(Socket clientSocket){
        this.clientSocket = clientSocket;
    }
    @Override
    public void run() {
        OutputStream outputStream = null;
        InputStream inputStream = null;
        BufferedReader reader = null;
        BufferedWriter writer = null;
        try {
            //让服务器一直监听是否有新的客户请求连接
            //建立通信:获取字节流
            inputStream = clientSocket.getInputStream();//输入流
            reader = new BufferedReader(new InputStreamReader(inputStream));
            outputStream = clientSocket.getOutputStream();//输出流
            writer = new BufferedWriter(new OutputStreamWriter(outputStream));
            while (true) {
                String s = null;
                s = reader.readLine();
                System.out.println("收到的消息为:" + s);
                if (s.equals("exit")) {
                    break;
                }

                //给客户端回复消息
                String str = "I receive your msg\n";//加回车把消息刷新出缓冲区
                writer.write(str);
                writer.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭资源
            try {
                outputStream.close();
                inputStream.close();
                reader.close();
                writer.close();
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

//Server端启动代码:在TCPServer中的代码
public void startServer() {
        try {
            while (true) {
                //让服务器一直监听是否有新的客户请求连接
                Socket clientSocket = socket.accept();
                new Thread(new ServerHandler(clientSocket)).start();

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
相关标签: java socket