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

TCP/IP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket,从而在通信的两端之间形成网络虚拟链路。一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信。Java对基于TCP协议的网络通信提供了良好的封装,Java使用Socket对象来代表两端的通信端口,并通过产生IO流来进行网络通信。
两个实体通信示意图
在这里插入图片描述
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();
        }
    }
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值