Java 基于 TCP 的 Socket 编程
创始人
2024-06-02 09:44:28

目录

1、TCP 协议

2、简单的 TCP 网络编程实现

3、一个服务端支持多个客户端连接的实现


1、TCP 协议

        TCP 协议,指传输控制协议(TCP,Transmission Control Protocol),是一种面向连接的、可靠的、基于字节流的传输层通信协议。

        在明白 TCP 协议概念的前提下,想要实现用 Java 程序来进行 TCP 编程其实不难,首先说一下编程中的相关概念:

  • IP:唯一的标识 Internet 上的某台计算机,在 Java 程序中通过 InetAddress 类获取 IP
  • 端口号:可以理解为计算机上运行的进程的入口,不同的进程有不同的端口号
  • Socket:这是一个比较抽象的概念,一个应用程序通过一个 Socket 来建立一个远程连接,而 Socket 内部通过 TCP/IP 协议把数据传输到网络,Socket 是两个进程之间网络通信的桥梁。

2、简单的 TCP 网络编程实现

        创建两个程序,一个充当服务器端,另一个充当客户端;服务器端会主动监听某个指定的端口,客户端必须主动连接服务器的 IP 地址和指定端口,如果连接成功,服务器端和客户端就成功地建立了一个 TCP 连接,双方后续就可以随时发送和接收数据。

        服务端程序的实现:

import java.net.*;
import java.io.*;public class TcpServer {public static void main(String[] args) {try {ServerSocket ss = new ServerSocket(8001); // 驻守在8001端口Socket s = ss.accept();                   // 阻塞,等到有客户端连接上来System.out.println("welcome to the java world");InputStream ips = s.getInputStream();     // 有client连上来,打开输入流OutputStream ops = s.getOutputStream();   // 打开输出流// 同一个通道,服务端的输出流就是客户端的输入流;服务端的输入流就是客户端的输出流ops.write("Hello, Client!".getBytes());  // 输出一句话给客户端BufferedReader br = new BufferedReader(new InputStreamReader(ips));// 从客户端读取一句话System.out.println("Client said: " + br.readLine());ips.close();ops.close();s.close();ss.close();} catch (Exception e) {e.printStackTrace();}}
}

        客户端程序的实现:

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;public class TcpClient {public static void main(String[] args) {try {Socket s = new Socket(InetAddress.getByName("127.0.0.1"), 8001); //需要服务端先开启// 同一个通道,服务端的输出流就是客户端的输入流;服务端的输入流就是客户端的输出流InputStream ips = s.getInputStream();    //开启通道的输入流BufferedReader brNet = new BufferedReader(new InputStreamReader(ips));OutputStream ops = s.getOutputStream();  //开启通道的输出流DataOutputStream dos = new DataOutputStream(ops);BufferedReader brKey = new BufferedReader(new InputStreamReader(System.in));while (true) {String strWord = brKey.readLine();if (strWord.equalsIgnoreCase("quit")) {break;} else {System.out.println("I want to send: " + strWord);// 向服务端发送数据(使用输出流)dos.writeBytes(strWord + System.getProperty("line.separator"));// 打印接收到的数据(使用输入流)System.out.println("Server said: " + brNet.readLine());}}dos.close();brNet.close();brKey.close();s.close();} catch (Exception e) {e.printStackTrace();}}
}

        分别启动服务端和客户端程序,演示效果如下:

        注意:服务端需要先于客户端启动,否则客户端因连接不到指定的进程而报错。同时输入输出流还可以传各种类型的数据,详情请参考 Java 的各种 I/O 流实现。

3、一个服务端支持多个客户端连接的实现

        实际场景中,一个服务端往往可以支持多个客户端的连接,为多个客户端提供服务。如下图所示:

        此处,为了实现上述想法,可以通过多线程改进一下服务端程序的实现:

import java.net.*;public class TcpServer2 {public static void main(String[] args) {try {ServerSocket serverSocket = new ServerSocket(8001);while (true) {Socket socket = serverSocket.accept();System.out.println("监听到 client 连接...");// 启动一个线程new Thread(new Worker(socket)).start();}//ss.close();} catch (Exception e) {e.printStackTrace();}}
}

        Worker.class 类的详情如下:

import java.net.*;
import java.io.*;class Worker implements Runnable {Socket socket;public Worker(Socket socket) {this.socket = socket;}public void run() {try {System.out.println("Worker 已经启动...");InputStream ips = socket.getInputStream();OutputStream ops = socket.getOutputStream();BufferedReader br = new BufferedReader(new InputStreamReader(ips));DataOutputStream dos = new DataOutputStream(ops);while (true) {String strWord = br.readLine();System.out.println("client said:" + strWord + ":" + strWord.length());if (strWord.equalsIgnoreCase("quit")){break;}String strEcho = strWord + " 666";// dos.writeBytes(strWord +"---->"+ strEcho +"\r\n");System.out.println("server said:" + strWord + "---->" + strEcho);dos.writeBytes(strWord + "---->" + strEcho + System.getProperty("line.separator"));}br.close();// 关闭包装类,会自动关闭包装类中所包装的底层类。所以不用调用ips.close()dos.close();socket.close();} catch (Exception e) {e.printStackTrace();}}
}

        分别启动服务端和客户端1和2后的演示效果如下:

        在客户端1,输入Hi:

        在客户端2,输入Hello:

        服务端的输出如下:

        至此,Java 基于 TCP 的 Socket 编程结束。有关 Java 基于 UDP 的 Socket 编程,可以参考我的这篇文章:《Java 基于 UDP 的 Socket 编程》。

相关内容

热门资讯

有色逆市狂飙!资金积极抢筹!有...   今日(1月15日)有色金属板块逆市领涨两市,板块热门ETF——有色ETF华宝(159876)场内...
百大集团跌2.02%,成交额1... 1月15日,百大集团盘中下跌2.02%,截至10:31,报14.55元/股,成交1.82亿元,换手率...
万润股份股价涨5.4%,广发基... 1月15日,万润股份涨5.4%,截至发稿,报17.36元/股,成交7.72亿元,换手率5.01%,总...
易华录2026年1月15日跌停... 2026年1月15日,易华录(sz300212)触及跌停,跌停价18.58元,涨幅-19.98%,总...
轻纺城涨2.23%,成交额55... 1月15日,轻纺城盘中上涨2.23%,截至10:32,报4.12元/股,成交5537.20万元,换手...