admin管理员组文章数量:1794759
【Java网络编程】从套接字(Socket)概念到UDP与TCP套接字编程
网络编程
1.socket套接字
Socket 套接字,是由系统提供用于网络通信的技术,是基于 TCP/IP 协议的网络通信的基本操作单元。基于Socket 套接字的网络程序开发就是网络编程。
Socket套接字可以基于传输层协议划分为三类:
- 流套接字:使用传输层TCP协议,基于字节流进行传输,对于字节流来说,可以简单的理解为,传输数据是基于IO流,流式数据的特征就是在IO流没有关闭的情况下,是无边界的数据,可以多次发送,也可以分开多次接收。
- 数据报套接字:使用传输层UDP协议,基于数据报进行传输,对于数据报来说,可以简单的理解为,传输数据是一块一块的,发送一块数据假如100个字节,必须一次发送,接收也必须一次接收100个字节,而不能分100次,每次接收1个字节。
- 原始套接字:原始套接字用于自定义传输层协议,用于读写内核没有处理的IP协议数据。
套接字(Socket)编程主要基于客户端-服务器模式之间的数据传递:
使用Socket编程时我们一般需要注意以下四点:
- 客户端和服务端:开发时,经常是基于一个主机开启两个进程作为客户端和服务端,但真实的场景,一般都是不同主机。
- 注意目的IP和目的端口号,标识了一次数据传输时要发送数据的终点主机和进程
- Socket编程我们是使用流套接字和数据报套接字,基于传输层的TCP或UDP协议,但应用层协议,也需要考虑。
- 关于端口被占用的问题:如果占用端口的进程A不需要运行,就可以关闭A后,再启动需要绑定该端口的进程B,如果需要运行A进程,则可以修改进程B的绑定端口,换为其他没有使用的端口。
Java实现了基于UDP和TCP两种模式的通信模型,下面我将对这两种模式相关的实现类进行讲解和演示。
2.udp数据报套接字编程
DatagramSocket API
DatagramSocket 是 UDP Socket ,用于发送和接收 UDP 数据报。
构造方法如下:
方法签名 | 方法说明 |
---|---|
DatagramSocket() | 创建一个 UDP 数据报套接字的 Socket ,绑定到本机任意一个随机端口(一般用于客户端) |
DatagramSocket(int port) | 创建一个 UDP 数据报套接字的 Socket ,绑定到本机指定的端口(一般用于服务端) |
3.tcp流套接字编程
ServerSocket API
ServerSocket 是创建TCP服务端Socket的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() | 返回此套接字的输出流 |
TCP中的长短连接
TCP 发送数据时,需要先建立连接,什么时候关闭连接就决定是短连接还是长连接:
短连接:每次接收到数据并返回响应后,都关闭连接,即是短连接。也就是说,短连接只能一次收发数据。
长连接:不关闭连接,一直保持连接状态,双方不停的收发数据,即是长连接。也就是说,长连接可以多次收发数据。
对比以上长短连接,两者区别如下:
- 建立连接、关闭连接的耗时:短连接每次请求、响应都需要建立连接,关闭连接;而长连接只需要第一次建立连接,之后的请求、响应都可以直接传输。相对来说建立连接,关闭连接也是要耗时的,长连接效率更高。
- 主动发送请求不同:短连接一般是客户端主动向服务端发送请求;而长连接可以是客户端主动发送请求,也可以是服务端主动发。
- 两者的使用场景有不同:短连接适用于客户端请求频率不高的场景,如浏览网页等。长连接适用于客户端与服务端通信频繁的场景,如聊天室,实时游戏等。
基于 BIO (同步阻塞 IO )的长连接会一直占用系统资源。对于并发要求很高的服务端系统来说,这样的消耗是不能承受的。实际应用时,服务端一般是基于NIO (即同步非阻塞 IO )来实现长连接,性能可以极大的提升。
Java基于TCP客户端-服务器代码实例
服务端代码如下:
代码语言:javascript代码运行次数:0运行复制import java.io.*;
import java.ServerSocket;
import java.Socket;
public class TcpServer {
//服务器socket要绑定固定的端口
private static final int PORT = 8888;
public static void main(String[] args) throws IOException {
// 1.创建一个服务端ServerSocket,用于收发TCP报文
ServerSocket server = new ServerSocket(PORT);
// 不停的等待客户端连接
while(true) {
System.out.println("------------------------------------------------
---");
System.out.println("等待客户端建立TCP连接...");
// 2.等待客户端连接,注意该方法为阻塞方法
Socket client = server.accept();
System.out.printf("客户端IP:%s%n",
client.getInetAddress().getHostAddress());
System.out.printf("客户端端口号:%s%n", client.getPort());
// 5.接收客户端的数据,需要从客户端Socket中的输入流获取
System.out.println("接收到客户端请求:");
InputStream is = client.getInputStream();
// 为了方便获取字符串内容,可以将以上字节流包装为字符流
BufferedReader br = new BufferedReader(new InputStreamReader(is,
"UTF-8"));
String line;
// 一直读取到流结束:TCP是基于流的数据传输,一定要客户端关闭Socket输出流才表示服
务端接收IO输入流结束
while ((line = br.readLine()) != null) {
System.out.println(line);
}
// 6.双方关闭连接:服务端是关闭客户端socket连接
client.close();
}
}
}
客户端代码如下:
代码语言:javascript代码运行次数:0运行复制import java.io.*;
import java.Socket;
public class TcpClient {
//服务端IP或域名
private static final String SERVER_HOST = "localhost";
//服务端Socket进程的端口号
private static final int SERVER_PORT = 8888;
public static void main(String[] args) throws IOException {
// 3.创建一个客户端流套接字Socket,并与对应IP的主机上,对应端口的进程建立连接
Socket client = new Socket(SERVER_HOST, SERVER_PORT);
// 4.发送TCP数据,是通过socket中的输出流进行发送
OutputStream os = client.getOutputStream();
// 为了方便输出字符串作为发送的内容,可以将以上字节流包装为字符流
PrintWriter pw = new PrintWriter(new OutputStreamWriter(os, "UTF-8"));
// 4-1.发送数据:
pw.println("hello world!");
// 4-2.有缓冲区的IO操作,真正传输数据,需要刷新缓冲区
pw.flush();
// 7.双方关闭连接:客户端关闭socket连接
client.close();
}
}
以上客户端与服务端建立的为短连接,每次客户端发送了 TCP 报文,及服务端接收了 TCP 报文后,双方都会关闭连接。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2024-10-26,如有侵权请联系 cloudcommunity@tencent 删除网络编程javaudpsocket编程本文标签: Java网络编程从套接字(Socket)概念到UDP与TCP套接字编程
版权声明:本文标题:【Java网络编程】从套接字(Socket)概念到UDP与TCP套接字编程 内容由林淑君副主任自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.xiehuijuan.com/baike/1754614146a1704397.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论