您的位置:首页 > 文旅 > 旅游 > 免费的全平台内容系统_文山seo_网推怎么做最有效_百度网站排名搜行者seo

免费的全平台内容系统_文山seo_网推怎么做最有效_百度网站排名搜行者seo

2024/12/23 7:30:36 来源:https://blog.csdn.net/qq_39464523/article/details/142755280  浏览:    关键词:免费的全平台内容系统_文山seo_网推怎么做最有效_百度网站排名搜行者seo
免费的全平台内容系统_文山seo_网推怎么做最有效_百度网站排名搜行者seo

一、概述

Socket(套接字)是网络通信的一种机制,允许不同主机之间的进程进行通信。在Java中,Socket支持TCP(传输控制协议)和UDP(用户数据报协议)。

1、TCP协议介绍

TCP协议在通信之前需要先建立连接,数据传输过程中能保证数据的完整性和顺序性。

2、UDP协议介绍

UDP协议可用于发送数据包,所需付出的开销比TCP协议少得多,但是UDP协议传输数据包时不会按照顺序传输,也可能会在数据传输中丢失数据。

二、socket编程步骤

1、创建一个Socket服务端,指定服务要监听的端口

// port为监听端口
ServerSocket socketServer = new ServerSocket(port);

2、监听客户端连接请求并接受连接

Socket socket = serverSocket.accept();

3、通过Socket对象获取输入流,用于读取客户端发送的数据

InputStream inputStream = socket.getInputStream();

完整代码:

InputStream inputStream = socket.getInputStream();
int len;
byte[] data = new byte[1024 * 1024];
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
while ((len = inputStream.read(data)) != -1) {byteArrayOutputStream.write(data, 0, len);
}
log.info("响应数据:{}", new String(byteArrayOutputStream.toByteArray()));

4、通过Socket对象获取输出流,用于向客户端发送数据

OutputStream outputStream = socket.getOutputStream();

完整代码:

// 发送数据
OutputStream outputStream = socket.getOutputStream();
outputStream.write("客户端1写入数据".getBytes());
// 超时时间,单位:毫秒
socket.setSoTimeout(timeout);
// 结束写入
socket.shutdownOutput();

5、创建Socket客户端,与客户端建立连接

// ip:服务端ip,port:服务端端口
Socket socket  = new Socket(ip, port);

三、socket服务端和socket客户端的完整代码

1、socket服务端

package com.xiaobai.java_core.socket;import lombok.extern.slf4j.Slf4j;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;/*** @Author 王天文* @Date 2024/12/15 17:02* @Description:*/
@Slf4j
public class SocketServerBIO {// 服务端监听器端口private static final int SERVER_PORT = 15000;public static void main(String[] args) {ServerSocket serverSocket = null;try {// 服务端绑定监听器端口serverSocket = new ServerSocket(SERVER_PORT);log.info("服务端启动,等待客户端连接,监听端口:{}", SERVER_PORT);while (true) {try {// 获取新的连接Socket socket = serverSocket.accept();log.info("客户端已连接,端口:{}", socket.getPort());// 每个连接创建一个线程(可使用ThreadPoolTaskExecutor或ThreadPoolExecutor创建线程)Thread connectThread = new Thread(new Runnable() {@Overridepublic void run() {String connectThreadName = Thread.currentThread().getName();log.info("连接线程名称,{}", connectThreadName);try {// 按字节流方式读取数据InputStream socketInputStream = socket.getInputStream();int len;byte[] data = new byte[1024 * 1024];ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();while ((len = socketInputStream.read(data)) != -1) {byteArrayOutputStream.write(data, 0, len);}log.info("客户端消息:{}", new String(byteArrayOutputStream.toByteArray()));// 客户端响应String responseMsg = "客户端响应消息" + "_" + connectThreadName;OutputStream socketOutputStream = socket.getOutputStream();log.info("客户端响应消息:{}", responseMsg);socketOutputStream.write(responseMsg.getBytes());// 服务端结束写入socket.shutdownOutput();} catch (IOException e) {e.printStackTrace();}}});connectThread.start();// 判断连接是否断开if (socket.isClosed()) {log.info("客户端连接已断开");}} catch (IOException e) {e.printStackTrace();}}} catch (IOException e) {e.printStackTrace();}}
}

2、socket客户端

package com.xiaobai.java_core.socket;import lombok.extern.slf4j.Slf4j;import java.io.*;
import java.net.Socket;/*** @Author 王天文* @Date 2024/12/15 18:02* @Description:*/
@Slf4j
public class SocketClient {private static final String SERVER_IP = "127.0.0.1";private static final int SERVER_PORT = 15000;private static final int timeout = 1800000;public static void main(String[] args) {Socket socket = null;try {// 与服务端建立连接socket  = new Socket(SERVER_IP, SERVER_PORT);// 发送数据OutputStream outputStream = socket.getOutputStream();outputStream.write("客户端1写入数据".getBytes());// 超时时间,单位:毫秒socket.setSoTimeout(timeout);// 结束写入socket.shutdownOutput();// 获取响应数据InputStream inputStream = socket.getInputStream();int len;byte[] data = new byte[1024 * 1024];ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();while ((len = inputStream.read(data)) != -1) {byteArrayOutputStream.write(data, 0, len);}log.info("响应数据:{}", new String(byteArrayOutputStream.toByteArray()));} catch (IOException e) {e.printStackTrace();} finally {if (socket != null) {try {socket.close();} catch (IOException e) {e.printStackTrace();}}}}
}

四、说明

1、阻塞问题

(1)BIO模式是同步阻塞I/O模式,数据的读取和写入必须阻塞在一个线程内等待完成;
(2)调用accept()方法后,当前线程处于挂起状态,系统层面得不到这个线程的运行权,其他客户端会处于阻塞状态,直到当前线程运行完毕;

2、解决方案

在服务端和客户端建立连接后,需要新建线程处理任务,使用线程池创建线程可防止内存溢出,提高线程的复用率,节省CPU资源。

学习小记 – 终于把线程状态流转理清楚了
Java面试常考的 BIO,NIO,AIO 总结

测试代码地址:
https://gitee.com/wangtianwen1996/cento-practice/tree/master/src/test/java/com/xiaobai/java_core/socket

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com