TCP通信 、 UDP通信
1. TCP通信
1.1. Socket通讯模型
1.1.1. Server端多线程模型
通过上一节我们已经知道了如何使用ServerSocket与Socket进行通讯了,但是这里存在着一个问题,就是只能“p2p”点对点。一个服务端对一个客户端。若我们想让一个服务端可以同时支持多个客户端应该怎么做呢?这时我们需要分析之前的代码。我们可以看到,当服务端的ServerSocket通过accept方法侦听到一个客户端Socket连接后,就获取该Socket并与该客户端通过流进行双方的通讯了,这里的问题在于,只有不断的调用accept方法,我们才能侦听到不同客户端的连接。但是若我们循环侦听客户端的连接,又无暇顾及与连接上的客户端交互,这时我们需要做的事情就是并发。我们可以创建一个线程类ClientHandler,并将于客户端交互的工作全部委托线程来处理。这样我们就可以在当一个客户端连接后,启动一个线程来负责与客户端交互,而我们也可以循环侦听客户端的连接了。
我们需要对服务端的代码进行修改:
copytextpop-up
/**
* Server端应用程序*
*/
public class Server {
public static void main(String[] args) {
ServerSocket server = null;
try {
//创建ServerSocket并申请服务端口为8088
server = new ServerSocket(8088);
while(true){
//循环侦听客户端的连接
Socket socket = server.accept();
//当一个客户端连接后,启动线程来处理该客户端的交互
new ClientHandler(socket).start();
}
} catch (Exception e) {
e.printStackTrace();
} finally{
if(server != null){
try {
server.close();
} catch (IOException e) {
}
}
}
}
}
/**
* 线程类
* 该线程的作用是并发与客户端进行交互
* 这里的代码就是原来在Server中客户端连接后交互的代码
*/
class ClientHandler extends Thread{
private Socket socket;
public ClientHandler(Socket socket){
this.socket = socket;
}
public void run(){
try {
//获取输入流,用于读取客户端发送过来的消息
InputStream in = socket.getInputStream();
BufferedReader reader
= new BufferedReader(
new InputStreamReader(
in,"UTF-8"
)
);
//获取输出流,用于向该客户端发送消息
OutputStream out = socket.getOutputStream();
PrintWriter writer
= new PrintWriter(
new OutputStreamWriter(
out,"UTF-8"
),true
);
//读取客户端发送的消息
String message = reader.readLine();
System.out.println("客户端说:"+message);
//向客户端发送消息
writer.println("你好客户端!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
/*** Server端应用程序**/
public class Server {public static void main(String[] args) {ServerSocket server = null;try {//创建ServerSocket并申请服务端口为8088server = new ServerSocket(8088);while(true){//循环侦听客户端的连接Socket socket = server.accept();//当一个客户端连接后,启动线程来处理该客户端的交互new ClientHandler(socket).start();}} catch (Exception e) {e.printStackTrace();} finally{if(server != null){try {server.close();} catch (IOException e) {}}}}
}
/*** 线程类* 该线程的作用是并发与客户端进行交互* 这里的代码就是原来在Server中客户端连接后交互的代码*/
class ClientHandler extends Thread{private Socket socket;public ClientHandler(Socket socket){this.socket = socket;}public void run(){try {//获取输入流,用于读取客户端发送过来的消息InputStream in = socket.getInputStream();BufferedReader reader= new BufferedReader(new InputStreamReader(in,"UTF-8"));//获取输出流,用于向该客户端发送消息OutputStream out = socket.getOutputStream();PrintWriter writer= new PrintWriter(new OutputStreamWriter(out,"UTF-8" ),true);//读取客户端发送的消息String message = reader.readLine();System.out.println("客户端说:"+message);//向客户端发送消息writer.println("你好客户端!");} catch (Exception e) {e.printStackTrace();}}
}
经过上面的改动,我们再次启动服务端,这个时候我们会发现,我们启动若干客户端都可以被服务器所接受并进行交互了。
2. UDP通信
2.1. DatagramPacket
2.1.1. 创建接收包
DatagramPacket:UDP数据报基于IP建立的,每台主机有65536个端口号可以使用。数据报中字节数限制为65536-8 。包含8字节的头信息。
构造接收包:
copytextpop-up
DatagramPacket(byte[] buf, int length)
DatagramPacket(byte[] buf, int length)
将数据包中Length长的数据装进Buf数组。
copytextpop-up
DatagramPacket(byte[] buf, int offset, int length)
DatagramPacket(byte[] buf, int offset, int length)
将数据包中从Offset开始、Length长的数据装进Buf数组。
2.1.2. 创建发送包
构造发送包:
copytextpop-up
DatagramPacket(byte[] buf, int length, InetAddress clientAddress, int clientPort)
DatagramPacket(byte[] buf, int length, InetAddress clientAddress, int clientPort)
从Buf数组中,取出Length长的数据创建数据包对象,目标是clientAddress地址,clientPort端口,通常用来发送数据给客户端。
copytextpop-up
DatagramPacket(byte[] buf, int offset, int length, InetAddress clientAddress, int clientPort)
DatagramPacket(byte[] buf, int offset, int length, InetAddress clientAddress, int clientPort)
从Buf数组中,取出Offset开始的、Length长的数据创建数据包对象,目标是clientAddress地址,clientPort端口,通常用来发送数据给客户端。
2.2. DatagramSocket
2.2.1. 服务端接收
DatagramSocke用于接收和发送UDP的Socket实例 。
copytextpop-up
DatagramSocket(int port)
DatagramSocket(int port)
创建实例,并固定监听Port端口的报文。通常用于服务端。
其中方法:
copytextpop-up
receive(DatagramPacket d)
receive(DatagramPacket d)
接收数据报文到d中。receive方法产生 “阻塞”。会一直等待知道有数据被读取到。
2.2.2. 客户端发送
无参的构造方法DatagramSocket()通常用于客户端编程,它并没有特定监听的端口,仅仅使用一个临时的。程序会让操作系统分配一个可用的端口。
其中方法:
copytextpop-up
send(DatagramPacket dp)
send(DatagramPacket dp)
该方法用于发送报文dp到目的地。
代码如下:
copytextpop-up
/**
* Server端程序
*/
public class Server {
public static void main(String[] args) {
DatagramSocket socket = null;
try {
socket = new DatagramSocket(8088);//申请8088端口
byte[] data = new byte[1024];
DatagramPacket packet
= new DatagramPacket(data, data.length);//创建接收包
socket.receive(packet);//会产生阻塞,读取发送过来的数据
String str = new String(packet.getData(),0,packet.getLength());//从 包中取数据
System.out.println(str);
} catch (Exception e) {
e.printStackTrace();
} finally{
if(socket != null){
socket.close();//关闭释放资源
}
}
}
}
/**
* Client端程序
*/
public class Client {
public static void main(String[] args) {
DatagramSocket socket = null;
try {
socket = new DatagramSocket();//创建Socket
byte[] data = "你好服务器!".getBytes();
DatagramPacket packet = new DatagramPacket(
data,
data.length,
InetAddress.getByName("localhost"),
8088
);//创建发送包
socket.send(packet);//发送数据
} catch (Exception e) {
e.printStackTrace();
} finally{
if(socket != null){
socket.close();//关闭以释放资源
}
}
}
}
/*** Server端程序*/public class Server {public static void main(String[] args) {DatagramSocket socket = null;try {socket = new DatagramSocket(8088);//申请8088端口byte[] data = new byte[1024];DatagramPacket packet= new DatagramPacket(data, data.length);//创建接收包socket.receive(packet);//会产生阻塞,读取发送过来的数据String str = new String(packet.getData(),0,packet.getLength());//从包中取数据System.out.println(str);} catch (Exception e) {e.printStackTrace();} finally{if(socket != null){socket.close();//关闭释放资源}}}
}
/*** Client端程序*/
public class Client {public static void main(String[] args) {DatagramSocket socket = null;try {socket = new DatagramSocket();//创建Socketbyte[] data = "你好服务器!".getBytes();DatagramPacket packet = new DatagramPacket(data, data.length,InetAddress.getByName("localhost"),8088);//创建发送包socket.send(packet);//发送数据} catch (Exception e) {e.printStackTrace();} finally{if(socket != null){socket.close();//关闭以释放资源}}}
}
TCP通信 、 UDP通信相关推荐
- Android Wifi连接控制、TCP、UDP通信,6.0以上适配
本文章包含内容 Wifi连接控制.Wifi广播接收,适配了Android6.0以上的版本 Wifi下的TCP通信 Wifi下的UDP通信 Github项目地址 码云项目地址 最近公司要开发智能家居,A ...
- [python学习] 专题七.网络编程之套接字Socket、TCP和UDP通信实例
很早以前研究过C#和C++的网络通信,参考我的文章: C#网络编程之Tcp实现客户端和服务器聊天 C#网络编程之套接字编程基础知识 ...
- 高性能 TCP amp; UDP 通信框架 HP-Socket v3.2.3 正式宣布
HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包括服务端组件.client组件和 Agent 组件.广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#. ...
- 网络通信、UDP通信、TCP通信、BS架构模拟、URL了解
网络编程 网络通信 网络通信三要素之IP地址(了解) JAVA对IP地址的操作(InetAddress类) 网络通信三要素之端口号(了解) 网络通信三要素之协议(了解) UDP通信 UDP通信之广播和 ...
- Socket之UDP通信
Socket之UDP通信 UDP通信原理: UDP协议是一种不可靠的网络协议,它在通信两端各自建立一个Socket对象,但是这两个Socket对象只是发送和接收数据的对象,因此基于UDP协议的通信双方 ...
- 40 张图带你搞懂 TCP 和 UDP
前言 拿下计网协议后,我就是公园里最靓的仔 TCP/IP 基础知识总结 计算机网络基础知识总结 那么下面就开始我们本篇文章,文章组织脉络如下 运输层位于应用层和网络层之间,是 OSI 分层体系中的第四 ...
- 【网络通信与信息安全】之深入解析TCP与UDP传输协议
一.什么是 socket ? Socket 的英文原义是"孔"或"插座".在编程中,Socket 被称做套接字,是网络通信中的一种约定.Socket 编程的应用 ...
- 【STM32+cubemx】0020 HAL库开发:以太网ENC28J60芯片和TCP、UDP简单应用
MCU通过以太网通信有很多种方式,有的内部自带以太网接口(如stm32f107的某些型号):如果没有,也可以在外围连接以太网芯片来实现.外接的以太网芯片,又分为带网络协议栈和不带协议栈的,带网络协议栈 ...
- [Unity Mirror] TCP 和 UDP
TCP 和 UDP 都是用于通过 Internet 发送信息的协议 - 事实上,它们是世界上最常用的两种 Internet 协议:TCP 是在 1970 年代开发的,而 UDP 是在 1980 年 ...
- TCP/IP协议学习笔记(二)TCP与UDP介绍
TCP/IP中有两个具有代表性的传输层协议,它们分别是TCP和UDP.TCP提供可靠的通信传输,而UDP则常被用于让广播和细节控制交给应用的通信传输. IP首部中有一个协议字段,用来标识网络层(IP) ...
最新文章
- [翻译] Ruby Golf
- 博士补贴125万,硕士70万本科21万,浙江某地人才(简直是抢人)新政!
- let const var 比较说明
- 深入理解正则表达式环视的概念与用法
- Oracle procedure调用实例
- PowerBuilder窗口之间传递多参数的方法
- 翻译软件(用百度的API实现)Python
- java导出pdf集合_java实现导出pdf-Go语言中文社区
- makemid+matlab,《MATLAB基础》双语课
- 工业以太网交换机的优势以及注意事项介绍
- 背景纹理素材|为前景元素添加焦点
- hdu 3631 Shortest Path(Floyd)
- 丛铭俣 160809324 (作业5)
- 关关php采集插件,推荐使用:关关采集器(杰奇全版本通用编码版)v3.5.00
- 阿里中台搞了3年,搞砸了?网传:副总裁玄难“背锅”,辞职创业!
- 关于创建String对象的抉择
- ffmpeg生成的视频与QuickTime不兼容
- D. Lizard Era: Beginning
- [RK3288][Android6.0] 主动从WLAN网络切换到移动数据网络
- keep-alive用法