예제 #1
0
        public HttpResponseHeader Send(HttpRequestHeader header, byte[] bodyData, out byte[] responseData)
        {
            //this function maybe raise these exception:
            //  SocketError.ConnectionReset
            //  SocketError.ConnectionAborted

            byte[] headData = header.GetHeaderRawData();
            _socket.Send(headData);

            if (bodyData != null && bodyData.Length > 0)
            {
                _socket.Send(bodyData);
            }

            //receive
            bool findingHeader = true;
            int  receiveOffset = 0;

            HttpResponseHeader response = new HttpResponseHeader();

            responseData = null;

            while (true)
            {
                if (findingHeader)
                {
                    #region receive header

                    if (receiveOffset >= _receiveHeaderBuffer.Length)
                    {
                        throw new InvalidDataException("Header data overflow");
                    }

                    int recByte = _socket.Receive(
                        _receiveHeaderBuffer,
                        receiveOffset,
                        _receiveHeaderBuffer.Length - receiveOffset,
                        SocketFlags.None);

                    if (recByte == 0)
                    {
                        throw new InvalidDataException("Invalid header data");
                    }

                    receiveOffset += recByte;

                    //contain body data
                    int headPos = seekSplitSymbolPosition(_receiveHeaderBuffer, 0, receiveOffset);
                    if (headPos > 0)
                    {
                        response.SetHeaderRawData(_receiveHeaderBuffer, 0, headPos);
                        responseData = new byte[response.ContentLength];

                        int tailLength = receiveOffset - headPos - 4;

                        if (tailLength > 0)
                        {
                            Buffer.BlockCopy(_receiveHeaderBuffer, headPos + 4, responseData, 0, tailLength);
                            receiveOffset = tailLength;
                        }
                        else
                        {
                            receiveOffset = 0;
                        }

                        //set flag
                        findingHeader = false;
                    }
                    #endregion
                }
                else
                {
                    #region receive body
                    if (receiveOffset > responseData.Length)
                    {
                        throw new InvalidDataException("Response data overflow");
                    }

                    if (receiveOffset == responseData.Length)
                    {
                        break;
                    }

                    int recByte = _socket.Receive(
                        responseData,
                        receiveOffset,
                        responseData.Length - receiveOffset,
                        SocketFlags.None);

                    if (recByte == 0)
                    {
                        break;
                    }

                    receiveOffset += recByte;

                    #endregion
                }
            }// end while

            if (receiveOffset != responseData.Length)
            {
                throw new InvalidDataException("Invalid response data length");
            }

            return(response);
        }
예제 #2
0
        public HttpResponseHeader Send(
            string serverEndPoint,
            HttpRequestHeader header,
            byte[] bodyData,
            out byte[] responseData)
        {
            SessionCollection col = null;

            for (int idx = 0; idx < _servers.Count; idx++)
            {
                if (_servers[idx].Key == serverEndPoint)
                {
                    col = _servers[idx].Value;
                    break;
                }
            }

            if (col == null)
            {
                throw new InvalidOperationException("The specify server endpoint not found");
            }

            bool reconnected = false;

            while (true)
            {
                int sid = 0;
                try
                {
                    TCPSession         session  = col.GetSession(out sid);
                    HttpResponseHeader response = session.Send(header, bodyData, out responseData);
                    col.ReleaseSession(sid);
                    return(response);
                }
                catch (ConnectionsOverflowException ex)
                {
                    //no enought idle session
                    //TODO:: logger
                    throw ex;
                }
                catch (SocketException ex)
                {
                    col.ReleaseAndDisposeSession(sid); //release session and dispose it

                    if (ex.SocketErrorCode == SocketError.ConnectionAborted ||
                        ex.SocketErrorCode == SocketError.ConnectionReset)
                    {
                        if (reconnected)
                        {
                            throw ex;
                        }
                        else
                        {
                            //need re-connect, and try once again
                            reconnected = true;
                            continue;
                        }
                    }
                    else
                    {
                        throw ex;
                    }
                }
                catch (InvalidDataException ex)
                {
                    col.ReleaseAndDisposeSession(sid); //release session and dispose it
                    if (reconnected)
                    {
                        throw ex;
                    }
                    else
                    {
                        //need re-connect, and try once again
                        reconnected = true;
                        continue;
                    }
                }
                catch (Exception ex)
                {
                    col.ReleaseAndDisposeSession(sid); //release session and dispose it
                    throw ex;
                }
            }
        }