Socket套接字
概念
Socket套接字是由系统提供用于网络通信的技术,是基于TCP/IP协议的网络通信的基本操作单元。基于Socket套接字的网络程序开发就是网络编程。
分类
Socket套接字主要针对传输层协议划分为如下三类:
流套接字
:使用传输层
TCP
协议
数据报套接字
:使用传输层
UDP
协议
原始套接字:原始套接字用于自定义传输层协议,用于读写内核没有处理的
IP
协议数据。
Java数据报套接字通信模型
对于UDP协议来说,有以下特点:
1)无连接
2)不可靠传输
3)面向数据报
4)有接受缓冲区,无发送缓冲区
5)大小受限,一次最多传输64k
java中使用UDP协议通信,主要是通过DatagramSocket类来创建数据报套接字。
并使用DatagramPacket作为发送或接受的UDP数据报。
Socket编程注意事项
1.
客户端和服务端:开发时,经常是基于一个主机开启两个进程作为客户端和服务端,但真实的场
景,一般都是不同主机。
2.
注意目的
IP
和目的端口号,标识了一次数据传输时要发送数据的终点主机和进程。
3. Socket
编程我们是使用流套接字和数据报套接字,基于传输层的
TCP
或
UDP
协议,但应用层协议,也需要考虑,这块我们在后续来说明如何设计应用层协议。
4. 关于端口被占用的问题,
如果一个进程
A
已经绑定了一个端口,再启动一个进程
B
绑定该端口,就会报错,这种情况也叫端
口被占用。
解决端口被占用的问题
:
- 如果占用端口的进程A不需要运行,就可以关闭A后,再启动需要绑定该端口的进程B
- 如果需要运行A进程,则可以修改进程B的绑定端口,换为其他没有使用的端口。
UDP数据报套接字编程
DatagramSocket API
方法签名 | 方法说明 |
DatagramSocket() |
创建一个
UDP
数据报套接字的
Socket
,绑定到本机任意一个随机端口(一般用于客户端)
|
DatagramSocket(int port) |
创建一个
UDP
数据报套接字的
Socket
,绑定到本机指定的端口(一般用于服务端)
|
方法签名 | 方法说明 |
void receive(DatagramPacket p)
|
从此套接字接收数据报(如果没有接收到数据报,该方法会阻塞等待)
|
void send(DatagramPacket
p)
|
从此套接字发送数据报包(不会阻塞等待,直接发送)
|
void close()
|
关闭此数据报套接字
|
DatagramPacket API
方法签名 | 方法说明 |
DatagramPacket(byte[]
buf, int length)
|
构造一个
DatagramPacket
以用来接收数据报,接收的数据保存在字节数组(第一个参数buf
)中,接收指定长度(第二个参数length)
|
DatagramPacket(byte[]
buf, int offset, int length, SocketAddress address)
|
构造一个
DatagramPacket
以用来发送数据报,发送的数据为字节数组(第一个参数buf
)中,从
0
到指定长度(第二个参数length)。
address
指定目的主机的
IP
和端口号
|
方法签名 | 方法说明 |
InetAddress getAddress()
|
从接收的数据报中,获取发送端主机
IP
地址;或从发送的数据报中,获取接收端主机IP
地址
|
int getPort()
|
从接收的数据报中,获取发送端主机的端口号;或从发送的数据报中,获取接收端主机端口号
|
byte[] getData()
|
获取数据报中的数据
|
InetSocketAddress API
TCP流套接字编程
ServerSocket API
方法签名 | 方法说明 |
ServerSocket(int port)
|
创建一个服务端流套接字
Socket
,并绑定到指定端口
|
方法签名 | 方法说明 |
Socket accept()
|
开始监听指定端口(创建时绑定的端口),有客户端连接后,返回一个服务端
Socket对象,并基于该Socket
建立与客户端的连接,否则阻塞等待
|
void close()
|
关闭此套接字
|
Socket API
Socket
是客户端
Socket
,或服务端中接收到客户端建立连接(
accept
方法)的请求后,返回的服务端Socket。
不管是客户端还是服务端
Socket
,都是双方建立连接以后,保存的对端信息,及用来与对方收发数据的。
方法签名 | 方法说明 |
Socket(String host, int port)
|
创建一个客户端流套接字
Socket
,并与对应
IP
的主机上,对应端口的进程建立连接
|
方法签名 | 方法说明 |
InetAddress getInetAddress()
|
返回套接字所连接的地址
|
InputStream getInputStream()
|
返回此套接字的输入流
|
OutputStream getOutputStream()
| 返回此套接字的输出流 |