Сетевое программирование в .NET. Расшифровка IP-адреса (IP address specification). Обеспечение надежности доставки пакетов, страница 33

To use the overlapped technique, a socket must be created with the WSASocket() function call using the overlapped enabled flag (the socket() function does not include this flag). Likewise, all data communication must be done using the WSARecv() and WSASend() functions. These Winsock functions use an overlapped I/O flag to indicate that the data will use the WSAOVERLAPPED data structure.

Although using overlapped I/O can greatly improve performance of the network program, it doesn’t solve all of the possible difficulties. One shortcoming of the overlapped I/O technique is that it can define only 64 events. For large-scale network applications that require hundreds of connections, this technique will not work.

Completion Ports

Another downside to the overlapped I/O technique is that all of the events are processed within a single thread in the program. To allow events to be split among threads, Windows introduced the completion port. A completion port allows the programmer to specify a number of threads for use within a program, and assign events to the individual threads. By combining the overlapped I/O technique with the completion port method, a programmer can handle overlapped socket events using separate program threads. This technique produces really interesting results on systems that contain more than one processor. By creating a separate thread for each processor, multiple sockets can be monitored simultaneously on each processor.



The Genesis UDP project is a class library that implements a lightweight UDP server and client using the .NET sockets functionality. It uses UDP to keep the amount of data being sent across the network low, and has many features such as basic encryption, sequenced packets, and a reliable channel.

Genesis communicates via command packets — a command packet is one or more UDP packets that have a 2 byte opcode, and a variable number of string fields. Unreliable packets can be up to 512 bytes, reliable packets can be longer but are split up by Genesis and sent in sequence. There are a few internal opcodes used by Genesis, but apart form that, how packets, opcodes and fields are handled is totally the responsibility of the host application developer.

There is also an optional encryption system, it is not too advanced but if enabled, will generate a random 320 bit key for each connecting client and use that key in an XOR encryption algorithm. This is quite secure as no two clients share the same key, however it relies on the initial connection packets not being sniffed. Adding public/private key encryption etc. is a possible enhancement to the library. It is possible to be selective over which connections are encrypted and which are not.

Servers vs. Clients

Genesis works on the basis that every instance of Genesis can be both a client and a server. The line between the client and the server is blurred, as any application that uses Genesis can both connect to servers and accept connections from clients. Of course, clients can't just connect by default - the appropriate events must be hooked in the host application to enable the functionality. A server is defined as the remote host that accepted the connection, whilst a client is the remote host that initiated the connection. As an instance of Genesis can do both, it can be both a server and client to other Genesis instances. Servers and clients are known collectively simply as hosts.


The diagram above shows how the idea of clients and servers works in Genesis. Each blue box represents an instance of the Genesis library - none are specifically designated servers or clients as both can potentially accept and initiate connections. The definition of server and client is only valid in the context of a single Genesis instance. Let us consider "Genesis 1", it is connected to servers 2 and 3, and 4 is connected as a client, this is determined by the directions of the arrows (the arrows represent which box initiated the connection). If we look at the perspective of "Genesis 2", we see there are just two clients, 1 and 3. However, if we look at the perspective of "Genesis 4", there is one server, "Genesis 1". Notice how "Genesis 1" can be both a client or server depending upon the context.