目录

一、常见的客户端服务端模型

二、Socket套接字

1、概念

2、分类

a、流套接字

b、数据报套接字

c、原始套接字

三、UDP数据报套接字编程

四、TCP数据报套接字编程


一、常见的客户端服务端模型

客户端:用户使用的程序。

服务端:给用户提供服务的程序。

整体流程:

  1. 客户端发送请求到服务端。
  2. 服务端根据客户端的的请求数据,执行相应的业务处理。
  3. 服务端返回响应:发送处理业务的处理结果。
  4. 客户端得到处理结果,展示处理结果。

二、Socket套接字

1、概念

Socket套接字是系统提供用于网络通信的技术,也是TCP/IP协议的网络通信的基本操作单元,并且基于Socket套接字的网络程序开发就是网络编程。

2、分类

a、流套接字

流套接字使用的是TCP协议(传输控制协议),TCP协议有如下特点:

  • 有连接。
  • 可靠通信。
  • 面向字节流传输。
  • 全双工。
  • 传输数据的大小不受限制。

全双工指的是通信双方可以同时发送数据进行通信,还有半双工通信:通信双方不能同时发送数据,单工通信就是只能由一方一直发送数据。

b、数据报套接字

数据报套接字使用的是UDP协议(用户数据报协议),UDP协议有如下的特点:

  • 无连接。
  • 不可靠。
  • 面向用户数据报传输。
  • 全双工。
  • 传输数据的大小有限制,一次最多传输64K。

c、原始套接字

原始套接字用于自定义传输层协议,用于读写内核没有处理的IP协议数据。

三、UDP数据报套接字编程

UDP编程具有两个核心类:

DatagramSocket:是UDP版本的Socket对象,用于接收和发送数据报。有如下三个方法:

receive:发送数据。

send:发送数据。

close:释放资源。

DatagramPacket:表示一个UDP数据报,每次发送和接收的都是DatagramPacket对象。

服务器端代码实现:

整体流程:

  1. 首先定义一个DatagramSocket对象,用于收发数据。
  2. 定义一个指定端口号的构造方法,在构造方法中完成实例化对象。
  3. 定义start方法中,循环处理请求:定义DatagramPacket对象接收请求,处理请求后,再定义一个DatagramPacket对象发送数据。
public class UDPEchoServer {//首先定义一个Socket对象private DatagramSocket datagramSocket = null;//构造方法:指定一个端口号public UDPEchoServer(int port) throws SocketException {datagramSocket = new DatagramSocket(port);}//启动服务器public void start() throws IOException {System.out.println("服务器已经启动!");while(true){//数据报DatagramPacket requestPacket = new DatagramPacket(new byte[1024],1024);//接收数据报datagramSocket.receive(requestPacket);//将接收到的数据报转成字符串String request = new String(requestPacket.getData(),0,requestPacket.getLength(),"UTF-8");//处理数据,返回响应String response = process(request);//将响应返回给客户端DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),0,response.getBytes().length,requestPacket.getSocketAddress());datagramSocket.send(responsePacket);//展示System.out.println("[客户IP"+responsePacket.getAddress()+"客户端口"+responsePacket.getPort()+"请求"+request+"响应"+response);}}//简单的回显服务来处理数据public String process(String request){return request;}public static void main(String[] args) throws IOException {UDPEchoServer udpEchoServer = new UDPEchoServer(9090);udpEchoServer.start();}
}

注意:

服务器的端口号一般是指定的,因为在客户端程序中需要指定服务器端的的端口号。

响应服务可以先别的,这里只是简单的回显服务。

客户端代码实现: 

整体流程:

  1. 首先定义一个DatagramSocket对象,用于收发数据。
  2. 定义一个构造方法指定服务器端的IP地址和端口号,并完成DatagramSocket对象实例。
  3. 定义start方法,循环发送请求,先定义DatagramPacket对象包装请求,发送到指定的服务器端,再定义一个DatagramPacket对象接收响应处理后的数据。
public class UDPEchoClient {//定义Socket对象DatagramSocket datagramSocket =null;private int serverPort;private String serverIP;//构造方法时传入的是服务器端的IP地址和端口号public UDPEchoClient(int port,String IP) throws SocketException {datagramSocket = new DatagramSocket();serverPort = port;serverIP = IP;}//启动客户端public void start() throws IOException {Scanner sc = new Scanner(System.in);while (true){System.out.println("发送请求>");String request = sc.next();//发送UDP请求DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(serverIP),serverPort);//发送数据datagramSocket.send(requestPacket);//读取数据并进行解析DatagramPacket responsePacket = new DatagramPacket(new byte[1024],1024);datagramSocket.receive(responsePacket);String response = new String(responsePacket.getData(),0,responsePacket.getLength(),"UTF-8");//打印响应结果System.out.println(response);}}public static void main(String[] args) throws IOException {UDPEchoClient udpEchoClient = new UDPEchoClient(2580,"127.0.0.1");udpEchoClient.start();}
}

注意:
客户端程序一般需要系统自动分配,因为你不知道此时那个端口号没有被占用,而且客户端的个数一般多于服务器端的数目。

在客户端的构造方法中需要指定服务器端的IP地址和端口号。

在启动程序时,先启动服务器端,再启动应用器端。

例如:将回显服务改变成数据+收到。

public class UDPEChoServer2 extends UDPEchoServer {public UDPEChoServer2(int port) throws SocketException {super(port);}public String  process (String request){return request+"收到";}public static void main(String[] args) throws IOException {UDPEChoServer2 udpeChoServer2 = new UDPEChoServer2(2580);udpeChoServer2.start();}
}

运行结果:

四、TCP数据报套接字编程

TCP编程的核心类:

ServerSocket:是服务器端的流套接字,创建实例对象时,可以绑定指定的端口,

accept方法:用于监听指定端口,有客户端连接的话就会返回一个Socket对象,基于该Socket对象与客户端建立连接,否则就会发生阻塞等待。

Socket:客户端与服务器端建立连接后,该类对象用于通信双方进行收发数据。创建实例对象时要绑定服务器端的IP地址和端口号。

有以下常用方法:

getInetAddress:返回套接字所连接的地址。

getInputStream:返回此套接字的输入流。

getOutputStream:返回此套接字的输出流。

服务器端代码实现

整体流程:

  1. 定义一个ServerSocket对象。
  2. 定义指定端口号的构造方法。
  3. 定义start方法来启动,创建Socket对象建立连接。
  4. 定义processConnection方法循环处理请求,先得到请求进行处理之后将结果返回给客户端。
public class TCPEchoServer {//定义一个服务器对象ServerSocket serverSocket =null;public TCPEchoServer(int port) throws IOException {serverSocket = new ServerSocket(port);}//开始public void start() throws IOException {System.out.println("服务器已经启动");while(true){//利用Socket对象来建立连接Socket clientSocket = serverSocket.accept();processConnection(clientSocket);}}private void processConnection(Socket clientSocket) {System.out.println("[" + clientSocket.getInetAddress().toString() + " "+clientSocket.getPort()+"]已经建立连接");try(InputStream inputStream = clientSocket.getInputStream()){try(OutputStream outputStream = clientSocket.getOutputStream()){//读取请求Scanner sc = new Scanner(inputStream);//循环处理请求while(true){if(!sc.hasNext()){System.out.println("[" + clientSocket.getInetAddress().toString() + "]已经断开连接");break;}String request = sc.next();//对请求做出响应String response = process(request);//将响应返回给客户端PrintWriter printWriter = new PrintWriter(outputStream);printWriter.println(response);//刷新缓存区,使客户端尽快得到响应结果printWriter.flush();}}} catch (IOException e) {e.printStackTrace();}}private String process(String request) {return request;}public static void main(String[] args) throws IOException {TCPEchoServer tcpEchoServer = new TCPEchoServer(9087);tcpEchoServer.start();}
}

客户端代码实现

整体流程

  1. 定义一个Socket对象。
  2. 定义一个指定服务器的IP地址和端口号的构造方法,并完成对Socket对象的实例。
  3. 定义start方法,循环发送请求,然后接收响应。
public class TCPEchoClint {Socket socket =null;public TCPEchoClint(int serverPort,String serverIP) throws IOException {//与指定的服务器端建立连接socket = new Socket(serverIP,serverPort);}//启动public void start(){System.out.println("客户端已经连接到服务器端");Scanner sc =new Scanner(System.in);try(InputStream inputStream = socket.getInputStream()) {try(OutputStream outputStream = socket.getOutputStream()){//循环发送请求while(true){String request = sc.next();//发送请求PrintWriter printWriter =new PrintWriter(outputStream);printWriter.println(request);printWriter.flush();Scanner scanner =new Scanner(inputStream);String response = scanner.next();System.out.println("response:"+response);}}} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) throws IOException {TCPEchoClint tcpEchoClint = new TCPEchoClint(9087,"127.0.0.1");tcpEchoClint.start();}}

但是这样实现服务器端代码存在BUG, 当再启动一个客户端就连接不到服务器,为什么呢?

原因分析:在服务器端的start方法中,利用while循环来建立连接,并调用processConnection方法,但是在processConnection方法中又有一个while循环处理请求,这样只要一个客户端请求未结束,别的客户端就连接不到服务器端,这显然不符合实际。

解决方案:在start方法中创建线程,使多个客户端能并发连接到服务器端。

public void start() throws IOException {System.out.println("服务器已经启动");while(true){//利用Socket对象来建立连接Socket clientSocket = serverSocket.accept();Thread t = new Thread(()-> processConnection(clientSocket)) ;t.start();}}

TCP/UDP网络编程相关推荐

  1. Java的TCP/UDP网络编程+多线程实现服务器端与客户端间的通信

    写在前面: Java为网络编程提供了丰富的库,我们能通过调用Socket套接字的方法实现服务器与客户端的双通信. 注意点: 需要注意的是端口的对应,端口可以理解为窗户,服务器只能通过某个端口(窗户)与 ...

  2. TCP/UDP(网络编程)

    TCP/UDP(大作业) 文章目录 TCP/UDP(大作业) Java 网络编程 1.1.描述TCP协议和UDP协议,并说出他们的区别与联系: 基于客户机-服务器模式的应用场景 2.什么是客户机-服务 ...

  3. TCP/UDP 网络编程实例

      TCP服务器: TCP_Server.c #include<stdio.h> #include <stdlib.h> #include <errno.h> #i ...

  4. TCP/UDP网络编程入门教程之二:TCP Server端——socket与文件描述符

    UNIX中的一切事物都是文件(everything in Unix is a file!) 当我在这篇教程中提到UNIX的时候,其意思专指符合UNIX标准的所谓"正统"UNIX的衍 ...

  5. 高等学校计算机科学与技术教材:tcp/ip网络编程技术基础,TCP/IP网络编程技术基础...

    TCP/IP网络编程技术基础 语音 编辑 锁定 讨论 上传视频 <TCP/IP网络编程技术基础>是2012年北京交通大学出版社出版的图书,作者是王雷. 书    名 TCP/IP网络编程技 ...

  6. JAVA UDP网络编程学习笔记

    一.UDP网络编程概述 采用TCP协议通信时,客户端的Socket必须先与服务器建立连接,连接建立成功后,服务器端也会持有客户端连接的Socket,客户端的Socket与服务器端的Socket是对应的 ...

  7. TCP/IP网络编程(3)

    基于DUP的服务端与客户端 在TCP/IP网络编程(2)中,介绍了TCP/IP的四层模型,传输层分为TCP和UDP两种方式,通过TCP套接字完成数据交换已经进行了介绍,下面介绍通过UDP套接字完成数据 ...

  8. TCP/IP网络编程(1)

    1. 套接字 套接字是由操作系统提供的网络数据通信软件设备,即使对网络数据传输原理不了解,也能够使用套接字完成网络数据传输.为了与远程计算机进行数据传输,需要连接到英特网,套接字就是进行网络连接的工具 ...

  9. TCP/IP网络编程之基于TCP的服务端/客户端(一)

    TCP/IP网络编程之基于TCP的服务端/客户端(一) 理解TCP和UDP 根据数据传输方式的不同,基于网络协议的套接字一般分为TCP套接字和UDP套接字.因为TCP套接字是面向连接的,因此又称为基于 ...

最新文章

  1. 矩阵变换应用-求演化矩阵
  2. AI对人类社会的真正威胁
  3. Facebook开源了超大规模图嵌入算法,上亿个节点也能快速完成
  4. 第03课:Spring Boot 启动原理
  5. Oceanus:美团HTTP流量定制化路由的实践
  6. ML的BD框架-Hadoop.Mahout.Strom.Spark/GraphLab
  7. java 先序遍历_二叉树的前序中序后序遍历(java代码)
  8. 使用 C# 编程对RTF文档的支持
  9. leetcode 82. 删除排序链表中的重复元素 II(map)
  10. 怎样才能培养孩子良好的用餐习惯
  11. 各种简单的困难的模板,持续更新
  12. 安卓ADB和Fastboot最新官方下载链接
  13. 为什么计算机屏幕出现黄色,电脑屏幕发黄的五种原因及处理方法
  14. ROS2入门教程—录制/回放数据
  15. FFmpeg合并ts文件为mp4文件
  16. 【2010.10.13 10:00 携程校招笔试】买可乐(50%)、派司机
  17. 全国短信息中心号码一览
  18. Statistic模块管理统计功能,用于提供应用内统计的能力,支持统计和分析用户属性和用户行为数据。通过plus.statistic可获取统计管理对象
  19. Django源码cookie解读:关于中文cookie会被吞掉并截断的问题。
  20. 在C ++中将二进制转换为十进制

热门文章

  1. linux如何升级内核版本
  2. 前后台加解密的使用--SHA256算法 RSA算法 AES算法
  3. The least populated class in y has only 1 member, which is too few. The minimum number of groups for
  4. 多线程编程:模拟商店对某件商品的进货与销售过程并将相关信息打印出来
  5. python-opencv车牌检测和定位
  6. 中国最高法院承认区块链证据具有法律约束力
  7. Android SoundTouch(处理音频)
  8. 性能测试大致分为以下六种
  9. 笛卡尔心形函数图像c语言,笛卡尔-心形图 源代码 分析
  10. 2021-2027全球与中国电动气控型呼吸机市场现状及未来发展趋势