Пример #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TcpServer" /> class.
 /// </summary>
 public TcpServer(TcpServerSettings settings)
 {
     Settings = settings;
 }
Пример #2
0
		private static Boolean TryConfigureBindAndStartListen(SOCKET serverSocket, TcpServerSettings settings)
		{
			// try disable use of the Nagle algorithm if requested
			if (settings.UseNagleAlgorithm == false)
			{
				var optionValue = -1;

				unsafe
				{
					var tryDisableNagle = WinsockInterop.setsockopt(serverSocket, WinsockInterop.IPPROTO_TCP, WinsockInterop.TCP_NODELAY, (Byte*) &optionValue, sizeof(Int32));

					// check if attempt has succeed
					if (tryDisableNagle == WinsockInterop.SOCKET_ERROR)
					{
						return false;
					}
				}
			}

			// try enable faster operations on the loopback if requested
			if (settings.UseFastLoopback)
			{
				unsafe
				{
					UInt32 optionValue = 1;

					UInt32 dwBytes;

					var tryEnableFastLoopbackResult = WinsockInterop.WSAIoctl(serverSocket, WinsockInterop.SIO_LOOPBACK_FAST_PATH, &optionValue, sizeof(UInt32), null, 0, out dwBytes, IntPtr.Zero, IntPtr.Zero);

					// check if attempt has succeed
					if (tryEnableFastLoopbackResult == WinsockInterop.SOCKET_ERROR)
					{
						return false;
					}
				}
			}

			// try bind
			{
				// compose address
				var address = new IN_ADDR
				{
					s_addr = 0
				};

				// compose socket address
				var socketAddress = new SOCKADDR_IN
				{
					sin_family = WinsockInterop.AF_INET,
					sin_port = WinsockInterop.htons(settings.Port),
					sin_addr = address
				};

				// try associate address with socket
				var tryBindResult = WinsockInterop.bind(serverSocket, ref socketAddress, SOCKADDR_IN.Size);

				if (tryBindResult == WinsockInterop.SOCKET_ERROR)
				{
					return false;
				}
			}

			// try start listen
			{
				var tryStartListen = WinsockInterop.listen(serverSocket, settings.AcceptBacklogLength);

				if (tryStartListen == WinsockInterop.SOCKET_ERROR)
				{
					return false;
				}
			}

			return true;
		}
Пример #3
0
		/// <summary>
		/// Activates server.
		/// </summary>
		public static TryResult<TcpWorker> TryInitialize(TcpServerSettings settings)
		{
			// 0 try initiates use of the Winsock DLL by a process
			{
				WSADATA data;

				var startupResultCode = WinsockInterop.WSAStartup(WinsockInterop.Version, out data);

				// check if startup was successful
				if (startupResultCode != WinsockErrorCode.None)
				{
					return TryResult<TcpWorker>.CreateFail(startupResultCode);
				}
			}

			// 1 try create server socket
			SOCKET serverSocket;

			{
				serverSocket = WinsockInterop.WSASocket(WinsockInterop.AF_INET, (Int32) SocketType.Stream, (Int32) ProtocolType.Tcp, IntPtr.Zero, 0, WinsockInterop.WSA_FLAG_REGISTERED_IO);

				// check if socket created
				if (WinsockInterop.INVALID_SOCKET == serverSocket)
				{
					goto FAIL;
				}
			}

			// 2 try initialize Registered I/O extension
			RIOHandle rioHandle;

			if (!RIOHandle.TryCreate(serverSocket, out rioHandle))
			{
				goto FAIL;
			}

			// 3 get count of processors
			var processorsCount = Environment.ProcessorCount;

			// 4 create collection of the IOCP workers
			var workers = new IocpWorker[processorsCount];

			// initialize workers
			for (var processorIndex = 0; processorIndex < processorsCount; processorIndex++)
			{
				// try create worker
				var tryCreateWorker = IocpWorker.TryCreate(rioHandle, processorIndex, 4096, 1024);

				// check if operation has succeed
				if (!tryCreateWorker.Success)
				{
					goto FAIL;
				}

				// add to collection
				workers[processorIndex] = tryCreateWorker.Result;
			}

			// try configure server socket and start listen
			if (!TryConfigureBindAndStartListen(serverSocket, settings))
			{
				goto FAIL;
			}

			// success
			var server = new TcpWorker(serverSocket, rioHandle, workers);

			foreach (var worker in workers)
			{
				worker.thread.Start();
			}

			return TryResult<TcpWorker>.CreateSuccess(server);

			FAIL:

			// get last error
			var errorCode = (WinsockErrorCode) WinsockInterop.WSAGetLastError();

			// terminate use of the Winsock DLL
			WinsockInterop.WSACleanup();

			// return fail
			return TryResult<TcpWorker>.CreateFail(errorCode);
		}
Пример #4
0
		/// <summary>
		/// Initializes a new instance of the <see cref="TcpServer" /> class.
		/// </summary>
		public TcpServer(TcpServerSettings settings)
		{
			Settings = settings;
		}
Пример #5
0
        private static Boolean TryConfigureBindAndStartListen(SOCKET serverSocket, TcpServerSettings settings)
        {
            // try disable use of the Nagle algorithm if requested
            if (settings.UseNagleAlgorithm == false)
            {
                var optionValue = -1;

                unsafe
                {
                    var tryDisableNagle = WinsockInterop.setsockopt(serverSocket, WinsockInterop.IPPROTO_TCP, WinsockInterop.TCP_NODELAY, (Byte *)&optionValue, sizeof(Int32));

                    // check if attempt has succeed
                    if (tryDisableNagle == WinsockInterop.SOCKET_ERROR)
                    {
                        return(false);
                    }
                }
            }

            // try enable faster operations on the loopback if requested
            if (settings.UseFastLoopback)
            {
                unsafe
                {
                    UInt32 optionValue = 1;

                    UInt32 dwBytes;

                    var tryEnableFastLoopbackResult = WinsockInterop.WSAIoctl(serverSocket, WinsockInterop.SIO_LOOPBACK_FAST_PATH, &optionValue, sizeof(UInt32), null, 0, out dwBytes, IntPtr.Zero, IntPtr.Zero);

                    // check if attempt has succeed
                    if (tryEnableFastLoopbackResult == WinsockInterop.SOCKET_ERROR)
                    {
                        return(false);
                    }
                }
            }

            // try bind
            {
                // compose address
                var address = new IN_ADDR
                {
                    s_addr = 0
                };

                // compose socket address
                var socketAddress = new SOCKADDR_IN
                {
                    sin_family = WinsockInterop.AF_INET,
                    sin_port   = WinsockInterop.htons(settings.Port),
                    sin_addr   = address
                };

                // try associate address with socket
                var tryBindResult = WinsockInterop.bind(serverSocket, ref socketAddress, SOCKADDR_IN.Size);

                if (tryBindResult == WinsockInterop.SOCKET_ERROR)
                {
                    return(false);
                }
            }

            // try start listen
            {
                var tryStartListen = WinsockInterop.listen(serverSocket, settings.AcceptBacklogLength);

                if (tryStartListen == WinsockInterop.SOCKET_ERROR)
                {
                    return(false);
                }
            }

            return(true);
        }
Пример #6
0
        /// <summary>
        /// Activates server.
        /// </summary>
        public static TryResult <TcpWorker> TryInitialize(TcpServerSettings settings)
        {
            // 0 try initiates use of the Winsock DLL by a process
            {
                WSADATA data;

                var startupResultCode = WinsockInterop.WSAStartup(WinsockInterop.Version, out data);

                // check if startup was successful
                if (startupResultCode != WinsockErrorCode.None)
                {
                    return(TryResult <TcpWorker> .CreateFail(startupResultCode));
                }
            }

            // 1 try create server socket
            SOCKET serverSocket;

            {
                serverSocket = WinsockInterop.WSASocket(WinsockInterop.AF_INET, (Int32)SocketType.Stream, (Int32)ProtocolType.Tcp, IntPtr.Zero, 0, WinsockInterop.WSA_FLAG_REGISTERED_IO);

                // check if socket created
                if (WinsockInterop.INVALID_SOCKET == serverSocket)
                {
                    goto FAIL;
                }
            }

            // 2 try initialize Registered I/O extension
            RIOHandle rioHandle;

            if (!RIOHandle.TryCreate(serverSocket, out rioHandle))
            {
                goto FAIL;
            }

            // 3 get count of processors
            var processorsCount = Environment.ProcessorCount;

            // 4 create collection of the IOCP workers
            var workers = new IocpWorker[processorsCount];

            // initialize workers
            for (var processorIndex = 0; processorIndex < processorsCount; processorIndex++)
            {
                // try create worker
                var tryCreateWorker = IocpWorker.TryCreate(rioHandle, processorIndex, 4096, 1024);

                // check if operation has succeed
                if (!tryCreateWorker.Success)
                {
                    goto FAIL;
                }

                // add to collection
                workers[processorIndex] = tryCreateWorker.Result;
            }

            // try configure server socket and start listen
            if (!TryConfigureBindAndStartListen(serverSocket, settings))
            {
                goto FAIL;
            }

            // success
            var server = new TcpWorker(serverSocket, rioHandle, workers);

            foreach (var worker in workers)
            {
                worker.thread.Start();
            }

            return(TryResult <TcpWorker> .CreateSuccess(server));

FAIL:

            // get last error
            var errorCode = (WinsockErrorCode)WinsockInterop.WSAGetLastError();

            // terminate use of the Winsock DLL
            WinsockInterop.WSACleanup();

            // return fail
            return(TryResult <TcpWorker> .CreateFail(errorCode));
        }