Java TCP异步数据接收

之前一直采用.Net编写服务端程序,最近需要切换到Linux平台下,于是尝试采用Java编写数据服务器。TCP异步连接在C#中很容易实现,网上也有很多可供参考的代码。但Java异步TCP的参考资料较少,网上例程多是阻塞多线程方法,由于线程的开销较大,当客户端较多时系统资源的消耗也较大。

综合网上和书本的相关知识,本文给出一个Java TCP异步接收数据的代码示例,并给出相关的注释。

/**
 * TcpAsyncServer.java
 */

import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.net.*;
import java.util.Iterator;

public class TcpAsyncServer {

    /*监听端口*/
    int port = 6000;
    /*缓冲区大小*/
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    /*其它相关定义*/
    Selector selector;
    ServerSocketChannel channel;
    ServerSocket socket;

    /*启动*/
    public void Start() throws Exception {
        /*初始化一个Selector*/
        selector = Selector.open();
        /*打开通道*/
        channel = ServerSocketChannel.open();
        /*非阻塞模式*/
        channel.configureBlocking(false);
        /*本机IP*/
        //InetAddress ip = InetAddress.getByName("127.0.0.1");
        InetAddress ip = InetAddress.getLocalHost();
        System.out.println(ip.toString());
        /*绑定IP和端口*/
        InetSocketAddress address = new InetSocketAddress(ip,port);
        socket = channel.socket();
        socket.bind(address);
        /*启动监听*/
        System.out.println("TCP服务器开始监听...");
        Listen();
    }

    /*停止*/
    public void Stop() throws Exception {
        channel.close();
        selector.close();
    }

    /*监听*/
    public void Listen() throws Exception {
        /*注册接收事件*/
        channel.register(selector,SelectionKey.OP_ACCEPT);
        /*无限循环*/
        while (true) {
            selector.select();
            /*轮询事件*/
            Iterator iter = selector.selectedKeys().iterator();
            while (iter.hasNext()) {
                SelectionKey key =  (SelectionKey)iter.next();
                iter.remove();
                /*事件分类处理*/
                if (key.isAcceptable()) {
                    ServerSocketChannel ssc = (ServerSocketChannel)key.channel();
                    SocketChannel sc = ssc.accept();
                    sc.configureBlocking(false);
                    sc.register(selector, SelectionKey.OP_READ);
                    System.out.println("新终端已连接:"+ sc.getRemoteAddress());
                }
                else if (key.isReadable()) {
                    SocketChannel sc = (SocketChannel)key.channel();
                    int recvCount = sc.read(buffer);
                    if (recvCount > 0) {
                        byte[] arr = buffer.array();
                        System.out.println(sc.getRemoteAddress() + "发来数据: "+ new String(arr));
                        buffer.flip();
                    }
                    else {
                        sc.close();
                    }
                    buffer.clear();
                }

                else {

                }

            }

        }

    }

}
/**
 * server.java
 */

public class server {

    public static void main(String[] args) throws Exception {

        TcpAsyncServer tcpServer = new TcpAsyncServer();
        tcpServer.Start();

    }
}

效果演示:

1. 利用TCP工具发送数据

3. 接收数据

时间: 2024-10-25 13:16:42

Java TCP异步数据接收的相关文章

C#异步数据接收串口操作类

C#异步数据接收串口操作类 使用C#调用传统32位API实现串口操作,整个结构特别的简单.接收数据只需要定义数据接收事件即可. 上传源代码我不会,需要源代码的请与我([email protected])联系.你也可以教我怎么上传源代码. using System; using System.Runtime.InteropServices; /// <summary> /// (C)2003-2005 C2217 Studio  保留所有权利 /// /// 文件名称:     IbmsSeri

TCP通信数据接收栈实现

很惭愧TCP/IP协议卷一还没有看完,实在是毅力问题. 在使用TCP的时候一向怀疑数据是否能够完整接受,先发送一个"hello"字符串后再发送一个"world"字符串,可能就会在你不知道的时候底层开始进行包的重组,重组成 "hellowo"和"rld"两个字符串.特别是在数据发送频繁,和网络延时的时候.如果你在接受方直接recv()缓冲区所有数据的时候,这种情况尤为常见. 我的解决方法是在程序内部使用一个栈区来解决这个问题,当

Sweet Snippet系列 之 TCP数据接收

Sweet Snippet系列 之 TCP数据接收 一.引子 虽说仍然是Sweet Snippet,不过本篇并没有代码,纯粹是自己觉得有点趣味,就索性一记了~ 二. 问题 接触过网络编程的朋友大概都应知道TCP,作为一种"流"式协议,TCP的粘包问题一直都是程序处理的要点,而这次的问题就是,如果发送n字节的TCP数据,对端接收时会出现多少种接收情况? 三. 解法 我们先从具体的一个实例来简单算一算吧~就假设我们发送了3个字节的TCP数据: 由于TCP如果接收成功至少可以接收一个字节,所

通过jquery的ajax异步请求接收返回json数据

jquery的ajax异步请求接收返回json数据方法设置简单,一个是服务器处理程序是返回json数据,另一种就是ajax发送设置的datatype设置为jsonp格式数据或json格式都可以. 代码示例如下: $('#send').click(function () { $.ajax({ type : "GET", url : "a.php", dataType : "jsonp", success : function (data) { $.

Java TCP/UDP socket 编程流程总结

最近正好学习了一点用java socket编程的东西.感觉整体的流程虽然不是很繁琐,但是也值得好好总结一下. Socket Socket可以说是一种针对网络的抽象,应用通过它可以来针对网络读写数据.就像通过一个文件的file handler就可以都写数据到存储设备上一样.根据TCP协议和UDP协议的不同,在网络编程方面就有面向两个协议的不同socket,一个是面向字节流的一个是面向报文的. 对socket的本身组成倒是比较好理解.既然是应用通过socket通信,肯定就有一个服务器端和一个客户端.

一种C# TCP异步编程中遇到的问题

最近在维护公司的一个socket服务端工具,该工具主要是提供两个socket server服务,对两端连接的程序进行数据的透明转发. 程序运行期间,遇到一个问题,程序的一端是GPRS设备,众所周知,GPRS设备的网络连接十分的不问题,由此会产生不少的"奇怪"问题.实际过程中,程序运行几个小时后,无线端的socket server断开就再也无法打开.找了很久都没发现. 通过wireshark抓取通信报文,一般是在TCP的三次握手时出的问题.常规的TCP三次握手,由TCP的标识可简单看作:

java Tcp Socket 传输图片代码

server端代码 import java.net.*; import java.io.*; public class ServerTcpListener implements Runnable{ public static void main(String[] args){ try{ final ServerSocket server = new ServerSocket(); InetAddress addr = java.net.Inet4Address.getLocalHost(); S

TCP二进制流接收

前几天,模拟了一个tcp发送与接收16进制的小程序.由于需求的改变现在需要接收二进制流式数据,下面记录一下客户端接收数据的实现的源码. package client; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.net.Socket; public class ClientSocket { static Socket socket = nul

Java TCP使用Socket进行网络图片传送(6)

作者 : 卿笃军 原文地址:http://blog.csdn.net/qingdujun/article/details/39338831 本文演示,使用Socket进行网络图片传送,实现客户端的client.bmp文件上传到服务端. 1)客户端,上传client.bmp图片给服务端,并接受服务端返回的"上传成功"消息. 2)服务端,接受客户端的图片并保存为server.bmp,同时给客户端发送"上传成功"消息. 客户端,代码如下: package upload.p