`
ansjsun
  • 浏览: 203820 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

socket服务类.在csdn花了5分下载下来的

阅读更多
我当时花了5分下载下来的.在这里免费发布..有参考价值要给我留言啊..做人要有人品的

package test.sockettest;
/**
 * 
 * @author chenjd
 */
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

public class NBServer {
	int port = 8090;
	int BUFFERSIZE = 1024;
	Selector selector = null;
	ServerSocketChannel serverChannel = null;
	HashMap clientChannelMap = null;// 用来存放每一个客户连接对应的套接字和通道

	public NBServer(int port) {
		this.clientChannelMap = new HashMap();
		this.port = port;
	}

	public void initialize() throws IOException {
		// 初始化,分别实例化一个选择器,一个服务器端可选择通道
		this.selector = Selector.open();
		this.serverChannel = ServerSocketChannel.open();
		this.serverChannel.configureBlocking(false);
		InetAddress localhost = InetAddress.getLocalHost();
		InetSocketAddress isa = new InetSocketAddress(localhost, this.port);
		this.serverChannel.socket().bind(isa);// 将该套接字绑定到服务器某一可用端口
	}

	// 结束时释放资源
	public void finalize() throws IOException {
		this.serverChannel.close();
		this.selector.close();
	}

	// 将读入字节缓冲的信息解码
	public String decode(ByteBuffer byteBuffer) throws CharacterCodingException {
		Charset charset = Charset.forName("ISO-8859-1");
		CharsetDecoder decoder = charset.newDecoder();
		CharBuffer charBuffer = decoder.decode(byteBuffer);
		String result = charBuffer.toString();
		return result;
	}

	// 监听端口,当通道准备好时进行相应操作
	public void portListening(String data) throws IOException, InterruptedException {
		// 服务器端通道注册OP_ACCEPT事件
		SelectionKey acceptKey = this.serverChannel.register(this.selector,
				SelectionKey.OP_ACCEPT);
		// 当有已注册的事件发生时,select()返回值将大于0
		while (acceptKey.selector().select() > 0) {
			System.out.println("event happened");
			// 取得所有已经准备好的所有选择键
			Set readyKeys = this.selector.selectedKeys();
			// 使用迭代器对选择键进行轮询
			Iterator i = readyKeys.iterator();
			while (i.hasNext()) {
				SelectionKey key = (SelectionKey) i.next();
				i.remove();// 删除当前将要处理的选择键
				if (key.isAcceptable()) {// 如果是有客户端连接请求
					System.out.println("more client connect in!");
					ServerSocketChannel nextReady = (ServerSocketChannel) key
							.channel();
					// 获取客户端套接字
					Socket s = nextReady.accept().socket();
					// 设置对应的通道为异步方式并注册感兴趣事件
					s.getChannel().configureBlocking(false);
					SelectionKey readWriteKey = s.getChannel().register(
							this.selector,
							SelectionKey.OP_READ | SelectionKey.OP_WRITE);
					// 将注册的事件与该套接字联系起来
					readWriteKey.attach(s);
					// 将当前建立连接的客户端套接字及对应的通道存放在哈希表//clientChannelMap中
					this.clientChannelMap.put(s, new ClientChInstance(s
							.getChannel()));
				} else if (key.isReadable()) {// 如果是通道读准备好事件
					System.out.println("Readable");
					// 取得选择键对应的通道和套接字
					SelectableChannel nextReady = (SelectableChannel) key
							.channel();
					Socket socket = (Socket) key.attachment();
					// 处理该事件,处理方法已封装在类ClientChInstance中
					this.readFromChannel(socket.getChannel(),
							(ClientChInstance) this.clientChannelMap
									.get(socket));
				} else if (key.isWritable()) {// 如果是通道写准备好事件
					System.out.println("writeable");
					// 取得套接字后处理,方法同上
					Socket socket = (Socket) key.attachment();
					SocketChannel channel = (SocketChannel) socket.getChannel();
//					this.writeToChannel(channel, "This is from server!");
					this.writeToChannel(channel, data);
				}
			}
		}
	}

	// 对通道的写操作
	public void writeToChannel(SocketChannel channel, String message)
			throws IOException {
		ByteBuffer buf = ByteBuffer.wrap(message.getBytes());
		int nbytes = channel.write(buf);
	}

	// 对通道的读操作
	public void readFromChannel(SocketChannel channel,
			ClientChInstance clientInstance) throws IOException,
			InterruptedException {
		ByteBuffer byteBuffer = null;
		try{
			byteBuffer = ByteBuffer.allocate(BUFFERSIZE);
			int nbytes = channel.read(byteBuffer);
		}catch(Exception e){
			clientChannelMap.remove(channel.socket());
			channel.close();
			e=null;
			return;
		}
		byteBuffer.flip();
		String result = this.decode(byteBuffer);
		// 当客户端发出”@exit”退出命令时,关闭其通道
		if (result.indexOf("@exit") >= 0||result.indexOf("q")>=0) {
			channel.close();
		}
//		else if(result.indexOf("@close") >= 0){//关闭服务
//			channel.close();
//			this.finalize();
//		}
		else {
			clientInstance.append(result.toString());
			// 读入一行完毕,执行相应操作
			if (result.indexOf("\n") >= 0) {
				System.out.println("client input" + result);
				clientInstance.execute();
			}
		}
	}

	// 该类封装了怎样对客户端的通道进行操作,具体实现可以通过重载execute()方法
	public class ClientChInstance {
		SocketChannel channel;
		StringBuffer buffer = new StringBuffer();

		public ClientChInstance(SocketChannel channel) {
			this.channel = channel;
		}

		public void execute() throws IOException {
			String message = "This is response after reading from channel!";
			writeToChannel(this.channel, message);
			buffer = new StringBuffer();
		}

		// 当一行没有结束时,将当前字窜置于缓冲尾
		public void append(String values) {
			buffer.append(values);
		}
	}

	// 主程序
	public static void main(String[] args) {
		NBServer nbServer = new NBServer(8090);
		try {
			nbServer.initialize();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(-1);
		}
		try {
			nbServer.portListening("This is from server!");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
分享到:
评论
6 楼 dizhuang 2012-02-13  
我搞不懂为什么需要注册Write事件,我注册Read了,一边读取一边处理不就可以了。
5 楼 chasewade 2012-02-10  
多谢分享啊
4 楼 lsrjava 2011-11-10  
学习一下,感谢楼主的分享啊
3 楼 wupuyuan 2011-09-14  
谢谢分享,一定要顶下
2 楼 maenliang1989 2011-09-14  
好一个事件驱动模型
1 楼 qitongster 2011-08-17  
我不知道是否有参考价值,但是很感谢你的这种奉献精神,5分不便宜啊!

没有到用socket编程的环境和境界,有机会再参考吧。

相关推荐

    winformSocket异步通信

    在.NET框架中,WinForm应用常常需要与外部设备或服务器进行数据交互,这时Socket通信就显得尤为重要。Socket是网络通信的基础组件,它提供了一种进程间通信(IPC)的能力,使得应用程序可以通过网络发送和接收数据。...

    Socket通信.zip

    5. **触摸轨迹**:在Android应用中,触摸轨迹是指用户在屏幕上触摸和滑动时,系统记录下来的点序列。这些轨迹可以用来分析用户的交互行为,例如在游戏或绘图应用中。 6. **数据传输**:在Socket通信中,数据通常以...

    Socket聊天程序示例

    Socket分为流式Socket(TCP)和数据报Socket(UDP)两种类型,本示例中很可能使用的是流式Socket,因为TCP提供的是面向连接、可靠的数据传输服务,适合于聊天这种需要稳定通信的应用场景。 接下来,我们来解析聊天...

    socketTool

    ★ 在一个程序内可进行多句柄/多类型的Socket的创建/删除/以及数据收发等操作 ★ 支持16进制的发送和16进制接收显示,支持汉字以及文本发送 ★ 用户可以方便的把接收到的数据保存下来 ★ 支持发送、接收字节...

    计算机网络实验报告,socket 编程 路由选择 csdn\CD

    5. 关闭连接:通信结束后,关闭socket。 在实验报告中,学生可能会展示如何实现这些步骤,包括使用`socket()`、`bind()`、`listen()`、`accept()`、`connect()`、`send()`和`recv()`等函数。此外,实验截图可能显示...

    Java TCP IP Socket

    1.4 服务指的是在服务器上运行的软件,它响应客户端的请求并提供相应服务。服务器和客户端的概念是相对的,一个程序可以同时是服务器和客户端。 1.5 套接字(Socket)是网络通信的端点,分为客户端套接字和服务器...

    delphi xe 10.4 socket聊天示例

    在本示例中,我们探讨的是使用Delphi XE 10.4开发的一个基于Socket通信的简单聊天应用。这个应用的核心技术包括TServerSocket和TClientSocket组件,SQLite3数据库,以及自定义类和数组的运用。让我们逐一深入解析...

    SocketTool工具源码

    建立Socket测试服务器端和测试客户端,并向支持各个端发送或接受报文数据,支持自动发送和自动应答,支持UDP和TCP,广播和组播,软件源码可以编译...我会定期把需要下载的积分降下来,减少大家的下载分数的硬性需求。

    C# Socket异步通信

    根据给定的文件信息,以下是对“C# Socket异步通信”的详细解析,重点在于如何在C#中实现Socket的异步通信。 ### C# Socket异步通信详解 #### 核心概念 在C#中,Socket编程是进行网络通信的基础技术之一。它允许...

    socket编程基础

    Socket编程是计算机网络通信的核心技术之一,特别是在C语言环境下,它是构建客户端-服务器应用程序的基础。本文将深入探讨Socket编程的基本概念、系统调用及其在实际编程中的应用。 首先,Socket编程始于`socket()`...

    CsharpSocket

    在"**CsharpSocket**"中,你可以看到如何使用C#的`System.Net.Sockets.TcpClient`和`TcpListener`类来实现TCP客户端和服务端的创建与通信。 接下来是**UDP(User Datagram Protocol)**。UDP是一种无连接的、不可靠...

    SuperSocket.MQTT:基于SuperSocket的MQTT协议实现

    1. **连接管理**:使用SuperSocket的SocketServer类,我们需要定义一个自定义的Session类来处理每个客户端的连接。这里需要实现连接建立、断开、心跳检测等基本功能。 2. **解析MQTT报文**:MQTT报文由固定头部、可...

    获得本机的用户名和IP地址

    在IT领域,获取本机的用户名和IP地址是常见的需求,尤其对于进行多播通讯的开发者来说更是必不可少的基础操作。本文将详细介绍如何在不同的操作系统环境下,包括Windows、Linux和macOS,获取这些信息。 首先,让...

    GOLANG语言实现SOCKET通讯粘包问题解决示例

    在TCP/IP通信中,"粘包"问题是一个常见的现象,主要出现在面向流的协议如TCP中。当多个数据包连续发送时,由于TCP的流水线特性,这些数据包可能会被合并成一个大的数据块,或者在接收端拆分不正确,导致接收方无法...

    android UDP socket通讯,演示demo

    在Android平台上进行网络通信时,UDP(User Datagram Protocol)socket是一种常用的方式,它提供了一种无连接、不可靠但高效的数据传输服务。本演示DEMO将深入解析如何在Android应用中实现UDP socket通信,帮助...

    springbootwebsocket实例.zip

    这个服务类中的`sendMessage`方法可以用于向指定的目的地发送消息。 **五、客户端使用WebSocket** 在客户端,通常使用JavaScript库如Socket.IO或Stomp.js来连接WebSocket服务器并发送/接收消息。例如,使用Stomp.js...

    socket套接字编程

    网络编程中,通常使用socket套接字编程,那么该如何使用呢?接下来我们做一个最基本的小程序实现其功能。博客地址:http://blog.csdn.net/bingdianlanxin,有问题欢迎留言!

    MFC 网络聊天工具

    在MFC中,我们通常使用CSocket类来处理Socket编程,它为开发者提供了创建、连接和发送/接收数据的接口。通过继承CSocket类,我们可以创建自己的网络通信类,添加我们需要的特定功能。 在MyChat项目中,客户端和...

    实战 自学python如何成为大佬(目录):https://blog.csdn.net/weixin-67859959/ar

    在Python学习的道路上,成为一位大佬并非易事,但通过实战和系统化的学习,任何人都有可能实现这一目标。本文将基于给定的资源目录,详细解析自学Python的过程中需要掌握的关键知识点,帮助你逐步进阶。 首先,目录...

Global site tag (gtag.js) - Google Analytics