java监听tcp端口被占用_监听TCP端口号:从简单Socket到NIO到Netty

一、思路

1. 监听端口:在服务器端创建一个ServerSocket对象,去监听某个端口

2. 创建连接:通过serverSocket.accept() 创建一个Socket对象,等待客户端连接,当有客户端连接到这个端口,Socket对象就创建成功

3. 接收消息:client.getInputStream() 阻塞式接收客户端往这个端口发送的消息

二、简单代码实现

public static void main(String[] args) throwsIOException {int port = 8234;//1. 创建ServerSocket对象,去监听端口号

try (ServerSocket serverSocket = newServerSocket(port)) {

System.out.println("启动程序监听8234端口...");

Socket client= null;

Boolean flag= true;while(flag) {//2. 创建Socket对象去等待客户端连接

client =serverSocket.accept();

System.out.println("客户端" + client.getInetAddress().getHostAddress() + "连接到服务器...");//3. 当客户端连接上之后,创建一个线程去处理这个客户端发送的数据,然后等待下一个客户端的连接

new Thread(newProcessDataThread(client)).start();

}

client.close();

System.out.println("服务器关闭");

}

}

public class ProcessDataThread implementsRunnable {privateSocket client;publicProcessDataThread(Socket socket) {this.client =socket;

}

@Overridepublic voidrun() {try{//1. 获取客户端发送过来的消息,此时是通过二进制流获取,也可以用InputStreamReader通过字符串接收

try (InputStream in =client.getInputStream()) {byte[] buffer = new byte[1024];while ((in.read(buffer)) != -1) {try{//2. 处理数据,如果处理发生异常,不影响下次接收数据

} catch(Exception ex) {

System.out.println("处理数据发生异常:" +ex);

}

}

}

}catch(Exception ex) {

System.out.println("客户端连接发生异常:" +ex);

}

}

}

三、NIO优化,但强烈不建议使用Java原生的NIO

1. 单线程

14c693dd09ba4e6875cfbbda314ab430.png

2. 多线程优化,对应上面的代码

67a35f4aad5e2b42c06e4517f0d88a15.png

3. 线程池优化

对于每一个请求,单独开一个线程进行相应的逻辑处理,如果客户端的数据传递是断断续续的,相应的线程需要I/O等待(有阻塞),并进行上线文切换(耗资源)

ab4745c78c65314a1ea2ba348a85672b.png

4. 使用NIO的Selector机制,提升程序并发效率

a. Channel用于连接和传输

b. Buffer 用于存储

c. 用于管理请求

4eab2a927d970a587f716de4a2215628.png

05450f1e3e43dc62cf2b84294a746b28.png

四、Netty优化

1. Netty是对NIO的进一步封装

2. Netty代码

io.netty

netty-all

4.1.6.Final

public classNettyServer {public static voidmain(String[] args) {

ServerBootstrap serverBootstrap= newServerBootstrap();

NioEventLoopGroup boos= newNioEventLoopGroup();

NioEventLoopGroup worker= newNioEventLoopGroup();

serverBootstrap

.group(boos, worker)

.channel(NioServerSocketChannel.class)

.childHandler(new ChannelInitializer() {protected voidinitChannel(NioSocketChannel ch) {

ch.pipeline().addLast(newStringDecoder());

ch.pipeline().addLast(new SimpleChannelInboundHandler() {

@Overrideprotected voidchannelRead0(ChannelHandlerContext ctx, String msg) {

System.out.println(msg);

}

});

}

})

.bind(8000);

}

}

public classNettyClient {public static void main(String[] args) throwsInterruptedException {

Bootstrap bootstrap= newBootstrap();

NioEventLoopGroup group= newNioEventLoopGroup();

bootstrap.group(group)

.channel(NioSocketChannel.class)

.handler(new ChannelInitializer() {

@Overrideprotected voidinitChannel(Channel ch) {

ch.pipeline().addLast(newStringEncoder());

}

});

Channel channel= bootstrap.connect("127.0.0.1", 8000).channel();while (true) {

channel.writeAndFlush(new Date() + ": hello world!");

Thread.sleep(2000);

}

}

}

参考:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用Netty监听TCP端口,你需要创建一个ServerBootstrap实例,并配置它的各种参数,然后调用bind()方法来绑定并监听指定的端口。 以下是一个简单的示例代码: ```java import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; public class TcpServer { private final int port; public TcpServer(int port) { this.port = port; } public void start() throws Exception { EventLoopGroup group = new NioEventLoopGroup(); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(group) .channel(NioServerSocketChannel.class) .localAddress(port) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new YourChannelHandler()); } }); ChannelFuture future = bootstrap.bind().sync(); future.channel().closeFuture().sync(); } finally { group.shutdownGracefully().sync(); } } public static void main(String[] args) throws Exception { int port = 8080; // 设置监听端口号 new TcpServer(port).start(); } } ``` 在上述代码中,我们创建了一个NioEventLoopGroup来处理事件的处理,ServerBootstrap用于引导和绑定服务器,NioServerSocketChannel用于接受传入的连接,ChannelInitializer用于初始化处理新的SocketChannel。 你需要将"YourChannelHandler"替换为你自己的实际处理程序,以处理接收到的数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值