0 0

TCP NIO连续发送多条消息时,服务端接收时会将多条消息合并,请帮忙分析。5

服务端代码:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;

public class TCPServerManager {
	
	private static final int PORT = 8089;
	
	private Charset charset = Charset.forName("UTF-8");
	
	private Selector selector = null;
	
	private ServerSocketChannel server = null;
	
	
	public void start() throws IOException{
		this.init();
		new Thread(new ReceiveWorker()).start();
	}


	private  void init() throws IOException{
		InetSocketAddress address  = null;
		selector = Selector.open();
		server = ServerSocketChannel.open();  
		
		address = new InetSocketAddress(PORT);
		server.socket().bind(address);
		server.configureBlocking(false);
		server.register(selector, SelectionKey.OP_ACCEPT);
	}
	
	
	
	/**
	 * 接收消息线程
	 * @author luozejun
	 *
	 */
	class ReceiveWorker implements Runnable{
		
		@Override
		public void run() {
			SelectionKey key = null;
			while(true){
				try {
					if(selector.select() > 0 );
					Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
					while (iterator.hasNext()) {
						key = iterator.next();
						iterator.remove();
						if(key.isAcceptable()){
							SocketChannel sc = server.accept();
							sc.configureBlocking(false);
							sc.register(selector, SelectionKey.OP_READ);
							key.interestOps(SelectionKey.OP_ACCEPT);
						}
						if(key.isReadable()){
							handlerMessage(key);
						}
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

		/**
		 * 消息处理
		 * @param key
		 */
		private void handlerMessage(SelectionKey key){
			ByteBuffer buffer = ByteBuffer.allocate(8*1024);
			SocketChannel channel = null;
			StringBuilder content = new StringBuilder();
			try{
				channel = (SocketChannel)key.channel();
				while(channel.read(buffer) > 0){
					buffer.flip();
					content.append(charset.decode(buffer));
				}
				System.out.println("接收:"+content);
			}catch (Exception e) {
				key.cancel();
				if(channel !=null){
					try {
						channel.close();
					} catch (IOException e1) {
						e1.printStackTrace();
					}
				}
				e.printStackTrace();
			}
		}
	}
	
	
	public static void main(String[] args) {
		TCPServerManager manager = new TCPServerManager();
		try {
			manager.start();
			System.out.println("server success");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
}


客户端发送代码
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;

public class TCPClient {
	
	private static final String HOST = "127.0.0.1";

	private static final int PORT = 8089;
	
	private Charset charset = Charset.forName("UTF-8");
	
	private Selector selector = null;
	
	private SocketChannel channel = null;
	
	/**
	 * 初始化
	 * @throws IOException
	 */
	private  void init() throws IOException{
		InetSocketAddress address  = null;
		selector = Selector.open();
		address = new InetSocketAddress(HOST,PORT);
		channel = SocketChannel.open(address);  
		channel.configureBlocking(false);
		channel.register(selector, SelectionKey.OP_READ);
	}
	
	/**
	 * 发送消息
	 * @param msgXml
	 * @throws IOException
	 */
	public void send(String msgXml) throws IOException{
		channel.write(charset.encode(msgXml));
	}
	
	
	public static void main(String[] args) throws IOException {
		TCPClient tcp = new TCPClient();
		tcp.init();
		
		tcp.send("您好啊");
		tcp.send(" 您在哪里");
		tcp.send(" 吃饭了没有");
		tcp.send( " 还没有哦");
		tcp.send( " 来我家吃吧");
		
		//这个无作用,只是不让线程停掉,防止TCP断开
		while(true){
			//
		}
	}
}


客户端发送了5条消息,而服务端接收将发送的消息合并了。

服务端打印结果:
接收:您好啊 您在哪里
接收: 吃饭了没有 还没有哦 来我家吃吧



因为需求是要求是批量发送消息,所以不希望线程等待。请各位一起分析下哪里需要调整。。
2014年6月23日 10:25

2个答案 按时间排序 按投票排序

0 0

TCP是流式管道,即使你是分多次调用发送接口发送数据,但是TCP可能组成一个包或者几个连续的包到对端,很容易就出现楼主所说的情况,楼主需要定义私有协议,对需要传输的数据进行包装。

2014年6月24日 01:04
0 0

最简单地方法:
客户端发送定长消息(length) 。
服务端接收时

ByteBuffer buffer = ByteBuffer.allocate(length);  


2014年6月23日 15:36

相关推荐

    nio socket编程java代码示例,客户端发送消息,服务端接收

    本示例将详细解析如何使用Java的非阻塞I/O(NIO)实现Socket通信,包括客户端发送消息和服务器端接收消息的过程。 首先,理解NIO(Non-blocking Input/Output)的概念至关重要。NIO与传统的IO模型不同,它提供了对...

    一个NIO服务端,客户端的例子

    Netty是一个基于NIO的高性能、异步事件驱动的网络应用程序框架,它极大地简化了网络编程,包括TCP和UDP协议的服务器和客户端应用开发。 在Java NIO中,核心组件包括通道(Channel)、缓冲区(Buffer)和选择器...

    Java NIO实现多个客户端之间的消息互发,客户端与服务器完整代码

    在这个场景下,Java NIO能够帮助服务器有效地处理多个客户端连接,并实现客户端之间消息的互发。 首先,我们要理解Java NIO的基本组件。主要包括通道(Channels)、缓冲区(Buffers)和选择器(Selectors)。通道是...

    Java NIO非阻塞服务端与客户端相互通信

    本教程将深入讲解如何使用Java NIO实现非阻塞服务端与客户端的通信。 1. **Java NIO基础** - **通道(Channels)**:NIO中的通道类似于传统IO的流,但它们可以同时读写,并且支持非阻塞操作。 - **缓冲区...

    分布式Java中的TCP/IP+NIO

    在提供的文档"tcp nio 服务端、客户端例子--参考《分布式Java应用:基础与实践》.doc"中,可能会包含具体的NIO服务端和客户端的代码示例,这些示例将展示如何使用`ServerSocketChannel`、`SocketChannel`、`Selector...

    多客户端和服务端通讯

    服务端需要维护一个客户端列表,当新客户端连接时,将新客户端的信息添加到列表中,并将上线消息发送给其他客户端。 群聊功能的实现,需要服务端能够接收来自任何客户端的消息,并将这些消息广播给所有在线的客户端...

    JAVA NIO 异步通信模板服务端

    当数据准备就绪时,服务端不会直接将结果返回给客户端,而是将其保存在缓冲区,等到客户端再次询问时再发送。这种方式避免了不必要的等待,提高了系统效率。 在`JavaNioTamplateServer`这个压缩包中,可能包含了...

    nio异步长连接服务端与客户端

    在这个主题中,我们将深入探讨NIO在实现异步长连接服务端与客户端时的关键知识点。 1. **NIO基础**: - **通道(Channels)**:NIO的核心组件之一,是数据传输的通道,如SocketChannel、ServerSocketChannel等。 ...

    默蓝网络通信测试工具(NIOSocket工具)支持TCP/IP和HTTP通信-网络通信开发人员必备

    该工具提供了服务端和客户端连接测试功能,包括单条发送、循环发送以及模拟多客户端发送,这些功能覆盖了网络通信的多种场景。单条发送适用于基本的请求响应测试,循环发送可用于验证持续通信的稳定性,而模拟多...

    JAVA nio异步长连接服务端与客户端

    在服务端,通常会创建一个NIO的Selector,用于监听多个Channel(通道)的读写事件。Selector通过register()方法注册Channel,并设置感兴趣的事件类型(如OP_READ或OP_WRITE)。然后在循环中调用select()方法,该方法...

    基于TCP协议的网络客户端及服务端的编写

    5. **拥塞控制**:当网络拥塞时,TCP会减慢发送速度,防止过多的数据涌入网络。常见的拥塞控制算法有慢启动、拥塞避免、快速重传和快速恢复等。 6. **关闭连接**:TCP连接是双向的,双方都可以发起关闭。通常采用四...

    多人聊天服务端和客户端 --异步接收发送数据

    本文将深入探讨"多人聊天服务端和客户端 --异步接收发送数据"这一主题,它涉及到的核心技术主要是Socket编程和客户端-服务器(CS)架构。 Socket编程是互联网应用程序之间进行通信的基础,它允许两台计算机通过网络...

    Java心跳包功能TCP实现

    服务器会在接收到连接请求时创建一个`Socket`对象来处理该连接。 - 实现一个循环,不断读取`Socket`的输入流,当接收到心跳包时,返回一个确认响应。 2. **创建TCP客户端**: - 使用`java.net.Socket`类建立到...

    异步TCP聊天程序(服务端和客户端)

    当接收到客户端的数据时,会将数据保存在缓冲区中,并且可以随时选择向任意一个或多个客户端发送回应。 客户端的主要任务: 1. **连接服务**:客户端首先需要建立到服务器的TCP连接,通过指定服务器的IP地址和端口...

    Java NIO实例UDP发送接收数据代码分享

    "Java NIO实例UDP发送接收数据代码分享" ...分享的代码展示了Java NIO实例UDP发送接收数据代码分享的完整示例,包括客户端和服务端完整代码,帮助开发者更好地理解Java NIO的使用和UDP数据包的发送和接收。

    tcp.zip_java Tcp _java nio_java nio TCP_tcp_tcp java

    Java NIO在处理TCP连接时,可以使用ServerSocketChannel监听客户端连接,并且通过Selector注册这些连接到一个或多个线程。这种方式提高了服务器的并发能力,因为一个线程可以处理多个连接,而不是每个连接都需要一个...

    联通SGIP1.2短信网关 发送接收短信皆可 可以应对高并发

    为了应对高并发的场景,使用了生产者和消费者典型的多线程设计方案,用线程池去管理多线程,需要改动相关代码,找到类SCIPServer修改即可,接收短信的方式有两种一种是Socket,一种是NIO,NIO实际测试会出现SP验证失败,所以...

    NIO服务端测试代码

    详情查看博客地址详情查看博客地址详情查看博客地址详情查看博客地址http://blog.csdn.net/g290095142/article/details/77848088

    服务端以NIO的方式处理请求的Demo

    在Java编程领域,NIO(Non-blocking Input/Output,非阻塞I/O)是一种重要的I/O模型...通过阅读和分析代码,你可以更深入地理解NIO在实际应用中的工作原理,以及如何将其应用于实际项目中,提升服务器处理请求的能力。

Global site tag (gtag.js) - Google Analytics