TCP通讯

发布时间:2023年12月27日

第二十一章 网络通信

本章节主要讲解的是TCP和UDP两种通信方式它们都有着自己的优点和缺点? 这两种通讯方式不通的地方就是TCP是一对一通信? UDP是一对多的通信方式? 接下来会一一讲解

TCP通信

TCP通信方式呢 ?主要的通讯方式是一对一的通讯方式,也有着优点和缺点 ?它的优点对比于UDP来说就是可靠一点 ?因为它的通讯方式是需要先发送消息 看看客户端是否能够接收到消息 如果没有回复消息的话 服务端 ?就不会发出文件 等待客户端回复消息,这个握手模式的话 ?就会非常可靠 ?以下代码进行讲解:

客户端代码:
package tcp;
?
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
?
/**
?* Socket客户端
?**/
public class SocketClient {
? ? public static void main(String[] args) {
? ? ? ? Socket s = null;
? ? ? ? try {
? ? ? ? ? ? // 与ip为127.0.0.1、端口为12345的服务端建立连接
? ? ? ? ? ? s = new Socket("127.0.0.1", 12345);
?
? ? ? ? ? ? // 创建输入流接收服务端发送的消息(字节流)
? ? ? ? ? ? InputStream is = s.getInputStream();
? ? ? ? ? ? // 将服务端返回的字节流转化为字符流
? ? ? ? ? ? InputStreamReader isr = new InputStreamReader(is);
? ? ? ? ? ? // 创建字符流读取缓冲区,方便每行读取
? ? ? ? ? ? BufferedReader br = new BufferedReader(isr);
?
? ? ? ? ? ? // 创建输出流返回消息
? ? ? ? ? ? OutputStream os = s.getOutputStream();
? ? ? ? ? ? // 创建输出流缓冲
? ? ? ? ? ? PrintWriter pw = new PrintWriter(os);
?
? ? ? ? ? ? // 创建发送消息的线程
? ? ? ? ? ? Runnable rOut = () -> {
? ? ? ? ? ? ? ? boolean flag = true;
? ? ? ? ? ? ? ? while (flag) {
? ? ? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? ? ? // 接收控制台输入
? ? ? ? ? ? ? ? ? ? ? ? Scanner scan = new Scanner(System.in);
? ? ? ? ? ? ? ? ? ? ? ? String msg = scan.nextLine();
? ? ? ? ? ? ? ? ? ? ? ? // 将输入写入缓冲
? ? ? ? ? ? ? ? ? ? ? ? pw.println(msg);
? ? ? ? ? ? ? ? ? ? ? ? // 将缓冲内的数据推送至服务端并清空缓冲区
? ? ? ? ? ? ? ? ? ? ? ? pw.flush();
? ? ? ? ? ? ? ? ? ? } catch (Exception e) {
? ? ? ? ? ? ? ? ? ? ? ? flag = false;
? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? };
?
? ? ? ? ? ? // 创建接收消息的线程
? ? ? ? ? ? Runnable rIn = () -> {
? ? ? ? ? ? ? ? boolean flag = true;
? ? ? ? ? ? ? ? while (flag) {
? ? ? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? ? ? // 逐行读取服务端返回的消息并打印
? ? ? ? ? ? ? ? ? ? ? ? String str = br.readLine();
? ? ? ? ? ? ? ? ? ? ? ? System.out.println("服务端的消息:" + str);
? ? ? ? ? ? ? ? ? ? } catch (IOException e) {
? ? ? ? ? ? ? ? ? ? ? ? flag = false;
? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? };
?
? ? ? ? ? ? // 启动两个线程
? ? ? ? ? ? Thread tOut = new Thread(rOut);
? ? ? ? ? ? Thread tIn = new Thread(rIn);
? ? ? ? ? ? tOut.start();
? ? ? ? ? ? tIn.start();
? ? ? ? }catch (IOException e) {
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? // 释放资源
? ? ? ? ? ? ? ? s.close();
? ? ? ? ? ? } catch (Exception exception) {
? ? ? ? ? ? ? ? exception.printStackTrace();
? ? ? ? ? ? }
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
}服务端代码:

package tcp;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
?
/**
?* Socket服务端
?**/
public class SocketServer {
? ? public static void main(String[] args) {
? ? ? ? ServerSocket ss = null;
? ? ? ? Socket s = null;
? ? ? ? try {
? ? ? ? ? ? // 创建监听端口为12345的Socket服务端
? ? ? ? ? ? ss = new ServerSocket(12345);
? ? ? ? ? ? System.out.println("服务端Socket服务已建立,等待客户端连接...");
? ? ? ? ? ? // 通过ss.accept()开始持续监听12345端口,当有连接时获取收到的包装成Socket的客户端对象
? ? ? ? ? ? s = ss.accept();
? ? ? ? ? ? // 获取客户端的IP地址和端口号
? ? ? ? ? ? String ip = s.getInetAddress().getHostAddress();
? ? ? ? ? ? int port = s.getPort();
? ? ? ? ? ? System.out.println("服务端与 " + ip + ":" + port + " 已建立连接");
?
? ? ? ? ? ? // 创建输入流接收客户端发送的消息(字节流)
? ? ? ? ? ? InputStream is = s.getInputStream();
? ? ? ? ? ? // 将客户端发送的字节流转化为字符流
? ? ? ? ? ? InputStreamReader isr = new InputStreamReader(is);
? ? ? ? ? ? // 创建字符流读取缓冲区,方便每行读取
? ? ? ? ? ? BufferedReader br = new BufferedReader(isr);
?
? ? ? ? ? ? // 创建输出流返回消息
? ? ? ? ? ? OutputStream os = s.getOutputStream();
? ? ? ? ? ? // 创建输出流缓冲
? ? ? ? ? ? PrintWriter pw = new PrintWriter(os);
?
? ? ? ? ? ? // 创建接受信息的线程
? ? ? ? ? ? Runnable rIn = () -> {
? ? ? ? ? ? ? ? boolean flag = true;
? ? ? ? ? ? ? ? while (flag) {
? ? ? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? ? ? // 逐行读取客户端发送的消息并打印
? ? ? ? ? ? ? ? ? ? ? ? String str = br.readLine();
? ? ? ? ? ? ? ? ? ? ? ? System.out.println("客户端的消息:" + str);
? ? ? ? ? ? ? ? ? ? } catch (IOException e) {
? ? ? ? ? ? ? ? ? ? ? ? flag = false;
? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? };
?
? ? ? ? ? ? // 创建发送消息的线程
? ? ? ? ? ? Runnable rOut = () -> {
? ? ? ? ? ? ? ? boolean flag = true;
? ? ? ? ? ? ? ? while (flag) {
? ? ? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? ? ? // 接收控制台输入
? ? ? ? ? ? ? ? ? ? ? ? Scanner scan = new Scanner(System.in);
? ? ? ? ? ? ? ? ? ? ? ? String msg = scan.nextLine();
? ? ? ? ? ? ? ? ? ? ? ? // 将输入写入缓冲
? ? ? ? ? ? ? ? ? ? ? ? pw.println(msg);
? ? ? ? ? ? ? ? ? ? ? ? // 将缓冲内的数据推送至客户端并清空缓冲区
? ? ? ? ? ? ? ? ? ? ? ? pw.flush();
? ? ? ? ? ? ? ? ? ? } catch (Exception e) {
? ? ? ? ? ? ? ? ? ? ? ? flag = false;
? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? };
?
? ? ? ? ? ? // 开启两个线程
? ? ? ? ? ? Thread tIn = new Thread(rIn);
? ? ? ? ? ? Thread tOut = new Thread(rOut);
? ? ? ? ? ? tIn.start();
? ? ? ? ? ? tOut.start();
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? // 释放资源
? ? ? ? ? ? ? ? ss.close();
? ? ? ? ? ? ? ? s.close();
? ? ? ? ? ? } catch (Exception exception) {
? ? ? ? ? ? ? ? exception.printStackTrace();
? ? ? ? ? ? }
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
}服务端代码图已经客户端的代码图:

?运行结果图如下所示:

缺点也从而发现 TCP程序是一对一的通信而如果碰到了需要发通知给好几个的话 这样的话需要重复这些操作这样就会很麻烦? 所以这里就需要使用到UDP通信?一对多来通信 下一个博客将会讲解UDP一对多通信?

文章来源:https://blog.csdn.net/2302_76551984/article/details/135213287
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。