Beispiel #1
0
        private void TryReceive()
        {
            if (!EnterReceiving())
            {
                return;
            }

            var buffer = _receiveDataBufferPool.Get();

            if (buffer == null)
            {
                CloseInternal(SocketError.Shutdown, "Socket receive allocate buffer failed.", null);
                ExitReceiving();
                return;
            }

            _receiveSocketArgs.SetBuffer(buffer, 0, buffer.Length);
            if (_receiveSocketArgs.Buffer == null)
            {
                CloseInternal(SocketError.Shutdown, "Socket receive set buffer failed.", null);
                ExitReceiving();
                return;
            }

            try
            {
                bool firedAsync = _receiveSocketArgs.AcceptSocket.ReceiveAsync(_receiveSocketArgs);
                if (!firedAsync)
                {
                    ProcessReceive(_receiveSocketArgs);
                }
            }
            catch (Exception ex)
            {
                ReturnReceivingSocketBuffer();
                CloseInternal(SocketError.Shutdown, "Socket receive error, errorMessage:" + ex.Message, ex);
                ExitReceiving();
            }
        }
        private void TryReceive()
        {
            if (!EnterReceiving())
            {
                return;
            }

            var buffer = _receiveDataBufferPool.Get();

            if (buffer == null)
            {
                CloseInternal(SocketError.Shutdown, "Socket receive allocate buffer failed.", null);
                ExitReceiving();
                return;
            }

            try
            {
                _receiveSocketArgs.SetBuffer(buffer, 0, buffer.Length);
                if (_receiveSocketArgs.Buffer == null)
                {
                    CloseInternal(SocketError.Shutdown, "Socket receive set buffer failed.", null);
                    ExitReceiving();
                    return;
                }
                //AcceptSocket:获取或设置要使用的套接字或创建用于接受与异步套接字方法的连接的套接字
                bool firedAsync = _receiveSocketArgs.AcceptSocket.ReceiveAsync(_receiveSocketArgs);
                if (!firedAsync)
                {
                    Task.Factory.StartNew(() => ProcessReceive(_receiveSocketArgs));
                }
            }
            catch (Exception ex)
            {
                CloseInternal(SocketError.Shutdown, "Socket receive error, errorMessage:" + ex.Message, ex);
                ExitReceiving();
            }
        }
Beispiel #3
0
        private Task SendHttp(IRequestContext context)
        {
            var incoming = context.Incoming;

            incoming.SendHeaders(context);

            var head = new StringBuilder();

            head.Append(incoming.Method);
            head.Append(' ');
            //head.Append(incoming.Scheme == Scheme.Https ? "https" : " http");
            //head.Append("://");
            //head.Append(incoming.DomainName);
            //head.Append(':');
            //head.Append(incoming.DestinationPort);
            head.Append(incoming.Path.HasValue ? incoming.Path.Value : "/");
            if (incoming.Query.HasValue)
            {
                head.Append(incoming.Query);
            }
            head.Append(' ');
            head.Append("HTTP/1.1");
            head.Append("\r\n");
            head.Append("Host: ");
            head.Append(incoming.DomainName);
            head.Append(":");
            head.Append(incoming.DestinationPort);
            head.Append("\r\n");

            if (incoming.Headers != null)
            {
                foreach (var header in incoming.Headers)
                {
                    if (string.IsNullOrEmpty(header.Key))
                    {
                        continue;
                    }

                    if (string.Equals("Connection", header.Key, StringComparison.OrdinalIgnoreCase) ||
                        string.Equals("Keep-Alive", header.Key, StringComparison.OrdinalIgnoreCase) ||
                        string.Equals("Host", header.Key, StringComparison.OrdinalIgnoreCase))
                    {
                        continue;
                    }

                    if (header.Value == null || header.Value.Length == 0)
                    {
                        continue;
                    }

                    foreach (var headValue in header.Value)
                    {
                        head.Append(header.Key);
                        head.Append(": ");
                        head.Append(headValue);
                        head.Append("\r\n");
                    }
                }
            }

            head.Append("Connection: Keep-Alive\r\n");
            head.Append("Keep-Alive: timeout=");
            head.Append((int)(_maximumIdleTime.TotalSeconds + 5));
            head.Append("\r\n\r\n");

            var headBytes = Encoding.ASCII.GetBytes(head.ToString());

            context.Log?.Log(LogType.TcpIp, LogLevel.Detailed, () => $"Writing {headBytes.Length} bytes of header to the connection stream");

            if (context.Log != null && context.Log.WillLog(LogType.TcpIp, LogLevel.VeryDetailed))
            {
                var headLines = head.ToString().Replace("\r", "").Split('\n');
                foreach (var headLine in headLines.Where(h => !string.IsNullOrEmpty(h)))
                {
                    context.Log.Log(LogType.TcpIp, LogLevel.VeryDetailed, () => $"> {headLine}");
                }
            }

            _stream.Write(headBytes, 0, headBytes.Length);

            return(Task.Run(() =>
            {
                if (incoming.Content != null && incoming.Content.CanRead)
                {
                    var buffer = incoming.ContentLength.HasValue ? _bufferPool.Get(incoming.ContentLength.Value) : _bufferPool.Get();
                    try
                    {
                        int Read()
                        {
                            var readTask = incoming.Content.ReadAsync(buffer, 0, buffer.Length);
                            readTask.Wait();

                            if (readTask.IsFaulted)
                            {
                                context.Log?.Log(LogType.Exception, LogLevel.Important, () => $"Connection failed to read from the incoming stream. {readTask.Exception.Message}");
                                throw new ConnectionException(this, "incoming read task faulted", readTask.Exception);
                            }

                            if (readTask.IsCanceled)
                            {
                                context.Log?.Log(LogType.TcpIp, LogLevel.Important, () => $"Timeout reading from the incoming stream");
                                throw new ConnectionException(this, "read task timed out");
                            }

                            var bytesRead = readTask.Result;

                            context.Log?.Log(LogType.TcpIp, LogLevel.Detailed, () => $"Read {bytesRead} bytes from the incoming stream");

                            return bytesRead;
                        }

                        void Write(int count)
                        {
                            var writeTask = _stream.WriteAsync(buffer, 0, count);
                            writeTask.Wait();

                            if (writeTask.IsFaulted)
                            {
                                context.Log?.Log(LogType.Exception, LogLevel.Important, () => $"Connection failed to write to Tcp stream. {writeTask.Exception.Message}");
                                throw new ConnectionException(this, "Tcp write task faulted", writeTask.Exception);
                            }

                            if (writeTask.IsCanceled)
                            {
                                context.Log?.Log(LogType.TcpIp, LogLevel.Important, () => $"Timeout writing to Tcp stream");
                                throw new ConnectionException(this, "Tcp write task timed out");
                            }
                        }

                        while (true)
                        {
                            var bytesRead = Read();
                            if (bytesRead == 0)
                            {
                                break;
                            }

                            context.Log?.Log(LogType.TcpIp, LogLevel.VeryDetailed, () => $"Read {bytesRead} bytes of content from the incomming stream");

                            Write(bytesRead);

                            context.Log?.Log(LogType.TcpIp, LogLevel.VeryDetailed, () => $"Wrote {bytesRead} bytes to the Tcp connection");
                        }
                    }
                    finally
                    {
                        _bufferPool.Reuse(buffer);
                    }
                }
            }));
        }