All Projects → jhg023 → Simplenet

jhg023 / Simplenet

Licence: mit
An easy-to-use, event-driven, asynchronous network application framework compiled with Java 11.

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to Simplenet

Simpletcp
Simple wrapper for TCP client and server in C# with SSL support
Stars: ✭ 99 (-39.63%)
Mutual labels:  server, tcp, tcp-server, tcp-client, client
Tinytcpserver
A small tcp server working under Mono or .NET (4.0) and provides hooks for handling data exchange with clients (works under mono and .net). Behaviour/protocol/reaction could be specified via custom C# script.
Stars: ✭ 14 (-91.46%)
Mutual labels:  server, network, tcp, tcp-server, tcp-client
Oksocket
An blocking socket client for Android applications.
Stars: ✭ 2,359 (+1338.41%)
Mutual labels:  server, tcp, tcp-server, tcp-client, client
Message Io
Event-driven message library for building network applications easy and fast.
Stars: ✭ 321 (+95.73%)
Mutual labels:  asynchronous, network, tcp, tcp-server
Zserver4d
ZServer4D 是一套从商业项目剥离而出的云服务器中间件,可以承载百万级的分布式负载服务,并且支持IoT及内网穿透
Stars: ✭ 199 (+21.34%)
Mutual labels:  server, network, tcp, client
twjitm-core
采用Netty信息加载实现长连接实时通讯系统,客户端可以值任何场景,支持实时http通讯、webSocket通讯、tcp协议通讯、和udp协议通讯、广播协议等 通过http协议,rpc协议。 采用自定义网络数据包结构, 实现自定义网络栈。
Stars: ✭ 98 (-40.24%)
Mutual labels:  tcp, maven, asynchronous, tcp-server
Bizsocket
异步socket,对一些业务场景做了支持
Stars: ✭ 469 (+185.98%)
Mutual labels:  tcp, tcp-server, tcp-client, client
Deta cache
缓存cache服务器
Stars: ✭ 106 (-35.37%)
Mutual labels:  server, network, tcp, tcp-server
React Native Tcp Socket
React Native TCP socket API for Android, iOS & macOS with client SSL/TLS support
Stars: ✭ 112 (-31.71%)
Mutual labels:  network, tcp, tcp-server, tcp-client
Node Minecraft Protocol
Parse and serialize minecraft packets, plus authentication and encryption.
Stars: ✭ 697 (+325%)
Mutual labels:  server, network, packets, client
Simpleunitytcp
🖧 Simple Unity Project to show how TCP communication are builded in C# without multi-threading or Unity network (Unet) involved.
Stars: ✭ 22 (-86.59%)
Mutual labels:  networking, tcp, tcp-server, tcp-client
Tk Listen
A library that allows to listen network sockets with proper resource limits and error handling
Stars: ✭ 27 (-83.54%)
Mutual labels:  asynchronous, network, tcp
Zeus
A high performance, cross-platform Internet Communication Engine. Developed with native socket API. Aim at handling millions of concurrent connections.
Stars: ✭ 30 (-81.71%)
Mutual labels:  server, tcp, client
Emodbus
Modbus library for both RTU and TCP protocols. Primarily developed on and for ESP32 MCUs.
Stars: ✭ 29 (-82.32%)
Mutual labels:  server, tcp, client
Go Raknet
An idiomatic Go library implementing a basic version of the RakNet protocol.
Stars: ✭ 40 (-75.61%)
Mutual labels:  server, network, client
Xdp
Package xdp allows one to use XDP sockets from the Go programming language.
Stars: ✭ 36 (-78.05%)
Mutual labels:  network, networking, packets
Pnet
High level Java network library
Stars: ✭ 49 (-70.12%)
Mutual labels:  network, networking, tcp
Packetsender
Network utility for sending / receiving TCP, UDP, SSL
Stars: ✭ 1,349 (+722.56%)
Mutual labels:  tcp, tcp-server, tcp-client
Simpletcp
A minimal non-blocking TCP server written for Python 3.
Stars: ✭ 162 (-1.22%)
Mutual labels:  tcp, tcp-server, tcp-client
Clientserverproject
一个C-S模版,该模版由三部分的程序组成,一个服务端运行的程序,一个客户端运行的程序,还有一个公共的组件,实现了基础的账户管理功能,版本控制,软件升级,公告管理,消息群发,共享文件上传下载,批量文件传送功能。具体的操作方法见演示就行。本项目的一个目标是:提供一个基础的中小型系统的C-S框架,客户端有三种模式,无缝集成访问,winform版本,wpf版本,asp.net mvc版本,方便企业进行中小型系统的二次开发和个人学习。同时网络组件方便的支持读写三菱和西门子PLC的数据,详细见Readme
Stars: ✭ 873 (+432.32%)
Mutual labels:  server, network, client

What is SimpleNet?

SimpleNet is a simplistic, client-server framework written in Java. One or more Client objects can connect to a Server and send data back-and-forth via TCP. Most methods that read data from the network are non-blocking and are invoked asynchronously when the requested data arrives. Not having to block a thread and wait for data is what makes SimpleNet scalable for different types of applications such as chat servers, multiplayer game servers, and so much more!

Maven/Gradle Dependency

  1. Add SimpleNet as a dependency using either Maven or Gradle:

Maven:

<dependency>
    <groupId>com.github.jhg023</groupId>
    <artifactId>SimpleNet</artifactId>
    <version>1.6.6</version>
</dependency>

Gradle:

implementation 'com.github.jhg023:SimpleNet:1.6.6'
  1. Because SimpleNet is compiled with Java 11, you must first require its module in your module-info.java:
module my.project {
    requires com.github.simplenet;
}

What do I need to know before using SimpleNet?

  • As stated above, SimpleNet is mostly callback-based. This means that you can request a specific amount of bytes, n, and specify what should be done with those n bytes, as if the Client or Server has already received them.
// Request a single byte and print it out when it arrives.
client.readByte(System.out::println);

// Continuously request a single byte and print it out when it arrives.
// 
// After the callback completes, another byte will be requested automatically, 
// and the same callback will be invoked. This continues until the connection is closed.
client.readByteAlways(System.out::println);
  • Packets are sent from a Client to a Server (and vice versa) via the Packet class.
// Create a packet that contains two bytes (with the value 42) and send it to a client.
Packet.builder().putByte(42).putByte(42).queueAndFlush(client);

// Create two packets with the specified data and queue them (but don't flush) to a client.
Packet.builder().putInt(123456).queue(client);
Packet.builder().putString("Hello World!").queue(client);

// Flush the queued packets to the client (these packets will be transformed into a single,
// big packet to improve throughput.
// 
// This method only needs to be called when using Packet#queue and not Packet#queueAndFlush.
client.flush();

Client Example

// Instantiate a new client.
var client = new Client();

// Register a connection listener.
client.onConnect(() -> {
    System.out.println(client + " has connected to the server!");
    
    // Builds a packet and sends it to the server immediately.
    Packet.builder().putByte(1).putInt(42).queueAndFlush(client);
});

// Register a pre-disconnection listener.
client.preDisconnect(() -> System.out.println(client + " is about to disconnect from the server!"));

// Register a post-disconnection listener.
client.postDisconnect(() -> System.out.println(client + " successfully disconnected from the server!"));

// Attempt to connect to a server AFTER registering listeners.
client.connect("localhost", 43594);

Server Example

// Instantiate a new server.
var server = new Server();

// Register one connection listener.
server.onConnect(client -> {
    System.out.println(client + " has connected!");

    /*
     * When one byte arrives from the client, switch on it.
     * If the byte equals 1, then request an int and print it
     * when it arrives.
     *
     * Because `readByteAlways` is used, this will loop when
     * the callback completes, but does not hang the executing thread.
     */
    client.readByteAlways(opcode -> {
        switch (opcode) {
            case 1:
                client.readInt(System.out::println);
        }
    });

    // Register a pre-disconnection listener.
    client.preDisconnect(() -> System.out.println(client + " is about to disconnect!"));

    // Register a post-disconnection listener.
    client.postDisconnect(() -> System.out.println(client + " has successfully disconnected!"));
});

// Bind the server to an address and port AFTER registering listeners.
server.bind("localhost", 43594);

Chat Server Example

To emphasize how easy it is to use SimpleNet, I have written an implementation of a scalable chat server below. Note how only two classes are required, ChatServer and ChatClient. Ideally, a chat server should use a GUI and not the console, as this leads to message cut-off in the window, but this is only to serve as a proof-of-concept.

The full ChatServer implementation is as follows:

public class ChatServer {
    public static void main(String[] args) {
        // Initialize a new server.
        var server = new Server();
        
        // Create a map that will keep track of nicknames on our chat server.
        var nicknameMap = new ConcurrentHashMap<Client, String>();
        
        // This callback is invoked when a client connects to this server.
        server.onConnect(client -> {
            // When a client disconnects, remove them from the nickname map.
            client.postDisconnect(() -> nicknameMap.remove(client));
            
            // Repeatedly read a single byte.
            client.readByteAlways(opcode -> {
                switch (opcode) {
                    case 1: // Change nickname
                        client.readString(nickname -> nicknameMap.put(client, nickname));
                        break;
                    case 2: // Send message to connected clients.
                        client.readString(message -> {
                            message = nicknameMap.get(client) + ": " + message;
                            server.queueAndFlushToAllExcept(Packet.builder().putString(message), client);
                        });
                        break;    
                }
            });
        });
        
        // Bind the server to our local network AFTER registering listeners.
        server.bind("localhost", 43594);
    }
}

The full ChatClient implementation is as follows:

public class ChatClient {
    public static void main(String[] args) {
        // Initialize a new client.
        var client = new Client();
        
        // This callback is invoked when this client connects to a server.
        client.onConnect(() -> {
            var scanner = new Scanner(System.in);
            
            // If messages arrive from other clients, print them to the console.
            client.readStringAlways(System.out::println);
            
            System.out.print("Enter your nickname: ");
            Packet.builder().putByte(1).putString(scanner.nextLine()).queueAndFlush(client);
            
            // Infinite loop to accept user-input for the chat server.
            while (true) {
                System.out.print("> ");
                
                // Read the client's message from the console.
                var message = scanner.nextLine();
                
                // If this client types "/leave", close their connection to the server.
                if ("/leave".equals(message)) {
                    client.close();
                    break;
                }
                
                // Otherwise, send a packet to the server containing the client's message.
                Packet.builder().putByte(2).putString(message).queueAndFlush(client);
            }
        });
        
        // Attempt to connect to a server AFTER registering listeners.
        client.connect("localhost", 43594);
    }
}

FAQ (Frequently-Asked Questions)

  • Can data be sent and received outside of the onConnect callback?
    • Yes, but only if the client is already connected to the server. However, this is not recommended unless you're well-versed in concurrency, as the onConnect callback is performed asynchronously.
  • Can a SimpleNet Client be used with some unrelated server and vice-versa?
    • Absolutely!
  • I have large packets that exceed the default buffer size; what can I do to avoid an exception?
    • Ideally, the best option would be to split your single, large packet into multiple, small packets.
    • If splitting the packet is not possible for any reason, both Client and Server have an overloaded constructor that accepts a buffer size in bytes. You can simply specify a size larger than 8192 (the default size).
  • Will Java 8 ever be supported again?
    • No, as Java 8 is no longer supported commercially as of January, 2019. SimpleNet will do its best to keep up with LTS releases. However, you're free to clone the project and build it on an older version of Java, as not many code changes are required.
  • What's next for SimpleNet?
    • Once Project Loom is complete and integrated into the mainline JDK, SimpleNet will be rewritten entirely; blocking I/O will be using fibers at that point, which will be much more scalable than my current implementation that uses a fixed thread pool.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].