public SimplexAsyncTransitStrategy(INetworkConnection con) { m_OwningConnection = con; LastUDPACKReceived = DateTime.MinValue; m_TCPSockState = new SockState(null, 0, null); m_TCPSockState.AsyncEventArgs = new SocketAsyncEventArgs(); }
/// <summary> /// 关闭连接 /// </summary> /// <returns></returns> public bool Close() { if (m_State == SockState.Idle) { return(true); } try { if (m_Socket.Connected) { m_Socket.Shutdown(SocketShutdown.Both); } m_Socket.Close(); //直接给逻辑回调 //m_Callee.OnSockClose(this); m_AsyncEvent.PushEvent(AsyncEvent.e_SocketEvent.E_SOCKETEVENT_CLOSED); InitSock(null); } catch (SocketException e) { m_State = SockState.Idle; SetSockError(e.ErrorCode, e.Message); } Init(); return(true); }
/// <summary> /// 关闭连接 /// </summary> /// <returns></returns> public bool Close() { if (m_State == SockState.Idle) { return(true); } if (m_Socket == null) { return(true); } try { if (m_Socket != null) { if (m_Socket.Connected) { m_Socket.Shutdown(SocketShutdown.Both); } m_Socket.Close(); m_Socket = null; } } catch (SocketException e) { m_State = SockState.Idle; SetSockError(e.ErrorCode, e.ToString()); } return(true); }
// Removes a SocketAsyncEventArgs instance from the pool. // returns SocketAsyncEventArgs removed from the pool. public SocketAsyncEventArgs Pop() { lock (this.pool) { SocketAsyncEventArgs args = null; if (pool.Count > 0) { args = this.pool.Pop(); } else { args = new SocketAsyncEventArgs(); byte[] buffer = new byte[1024]; args.SetBuffer(buffer, 0, buffer.Length); SockState recState = new SockState(args, buffer.Length, null); recState.IsCached = false; recState.ID = Interlocked.Decrement(ref SockStateID); args.UserToken = recState; recState.BufferBlockOffset = 0; recState.BufferBlockLength = 1024; } return args; } }
/// <summary> /// 设置状态 /// </summary> /// <param name="state"></param> public void SetSockState(SockState state) { //lock (m_StateLock) { m_State = state; //Log.Trace("state " + m_State.ToString()); } }
public void AssembleInboundPacket(byte[] buffer, int bytesReceived, SockState state) { try { int incomingPointer = 0; // how much of the incoming data have we read while (incomingPointer < bytesReceived) { if (state.MessageLength == -1) // don't know how long the message is, still need to read the envelope { int leftForEnvelope = SockState.EnvelopeLength - state.PacketBufferPointer.Position; int numToCopy = leftForEnvelope; int leftInBlock = bytesReceived - incomingPointer; if (numToCopy > leftInBlock) { numToCopy = leftInBlock; } Util.Copy(buffer, state.BufferBlockOffset + incomingPointer, state.PacketBuffer, state.PacketBufferPointer.Advance(numToCopy), numToCopy); incomingPointer += numToCopy; if (state.PacketBufferPointer.Position >= SockState.EnvelopeLength) { state.MessageLength = BitConverter.ToInt32(state.PacketBuffer, 0); state.PacketTypeID = BitConverter.ToInt32(state.PacketBuffer, 4); state.PacketSubTypeID = BitConverter.ToInt32(state.PacketBuffer, 8);// state.PacketBuffer[8]; state.Flags = (PacketFlags)state.PacketBuffer[12]; state.PacketBufferPointer.Reset(); state.PacketBuffer = new byte[state.MessageLength]; continue; } return; } int bytesNeededToCompleteMessage = state.PacketBuffer.Length - state.PacketBufferPointer.Position; int bytesToRead = bytesNeededToCompleteMessage; if (bytesToRead > bytesReceived - incomingPointer) { bytesToRead = bytesReceived - incomingPointer; } Util.Copy(buffer, state.BufferBlockOffset + incomingPointer, state.PacketBuffer, state.PacketBufferPointer.Advance(bytesToRead), bytesToRead); incomingPointer += bytesToRead; if (state.PacketBufferPointer.Position >= state.MessageLength) { DeserializePacket(state); state.Reset(); } } } catch (Exception readExc) { Log.LogMsg(readExc.Message + ": Shutting down socket.\r\n" + readExc.StackTrace); KillConnection(""); } }
public bool StartListening(AddressFamily family, int port, Func<IPEndPoint, INetworkConnection> getConMethod) { try { GetConnnection = getConMethod; if (Socket == null) { Socket = new System.Net.Sockets.Socket(family, SocketType.Dgram, ProtocolType.Udp); Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); Socket.ExclusiveAddressUse = false; if (family == AddressFamily.InterNetworkV6) { Socket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, 0); // set IPV6Only to false. enables dual mode socket - V4+v6 Socket.Bind(new IPEndPoint(IPAddress.IPv6Any, port)); } else { Socket.Bind(new IPEndPoint(IPAddress.Any, port)); } } Port = ((IPEndPoint)Socket.LocalEndPoint).Port; m_ListenArgs = new byte[1024]; m_ListenerThread = new Thread(new ThreadStart(DoListen)); m_ListenerThread.IsBackground = true; m_ListenerThread.Name = "UDPListenerSimplex Read Thread"; m_State = new SockState(null, 1024, null); if (family == AddressFamily.InterNetworkV6) { m_EndPoint = new IPEndPoint(IPAddress.IPv6Any, 0); } else { m_EndPoint = new IPEndPoint(IPAddress.Any, 0); } m_ListenerThread.Start(); } catch (Exception e) { Log.LogMsg("UDPListenerSimplex - error start listen: " + e.Message); return false; } Listening = true; Log.LogMsg("UDPListenerSimplex - Listening for UDP traffic on port " + port.ToString()); return true; }
/// <summary> /// 设置状态 /// </summary> /// <param name="state"></param> private void SetSockState(SockState state) { //lock (m_StateLock) { m_State = state; if (state == SockState.Connected || state == SockState.Connecting) { mbConnected = true; } else if (state == SockState.Failed || state == SockState.Idle) { mbConnected = false; } //LogSystem.Log("state " , m_State.ToString()); } }
//If Host is an IP doesn't resolve anything and returns a //a 32 bits long IP. //If Host isn't an IP then returns vbNull, tries to resolve it //in asynchronous way and acts according to enmDestination. private int ResolveIfHostname(string Host, DestResolucion enmDestination) { int functionReturnValue = 0; int lngAddress = 0; lngAddress = api_inet_addr(Host); int lngAsynHandle = 0; int lngErrorCode = 0; bool blnCancelDisplay = false; //if Host isn't an IP if (lngAddress == modSocketMaster.INADDR_NONE) { functionReturnValue = VariantType.Null; m_enmState = SockState.sckResolvingHost; Debug.Print("STATE: sckResolvingHost"); if (AllocateMemory()) { //UPGRADE_ISSUE: ObjPtr function is not supported. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="367764E5-F3F8-4E43-AC3E-7FE0B5E074E2"' lngAsynHandle = modSocketMaster.ResolveHost(Host, m_lngMemoryPointer, VarPtr.VarPtr(this)); if (lngAsynHandle == 0) { FreeMemory(); m_enmState = SockState.sckError; Debug.Print("STATE: sckError"); lngErrorCode = Err().LastDllError; blnCancelDisplay = true; if (Error_Renamed != null) { Error_Renamed(lngErrorCode, modSocketMaster.GetErrorDescription(lngErrorCode), 0, "CSocketMaster.ResolveIfHostname", "", 0, blnCancelDisplay); } if (blnCancelDisplay == false) Interaction.MsgBox(modSocketMaster.GetErrorDescription(lngErrorCode), MsgBoxStyle.OkOnly, "CSocketMaster.ResolveIfHostname"); } else { m_colWaitingResolutions.Add(enmDestination, "R" + lngAsynHandle); Debug.Print("Resolving host " + Host + " with handle " + lngAsynHandle); } } else { m_enmState = SockState.sckError; Debug.Print("STATE: sckError"); Debug.Print("Error trying to allocate memory"); Err().Raise(modSocketMaster.sckOutOfMemory, "CSocketMaster.ResolveIfHostname", "Out of memory"); } //if Host is an IP doen't need to resolve anything } else { functionReturnValue = lngAddress; } return functionReturnValue; }
//**************************************************************** // エラー(切断)発生時にステータスの変更とLastErrorを設定するメソッド //**************************************************************** protected void SetException(Exception ex) { _lastError = string.Format("[{0}] {1}", ex.Source, ex.Message); SockState = SockState.Error; }
/// <summary> /// Gets called when a send operation resolves. /// </summary> private void OnSendResolved(SocketAsyncEventArgs args, SockState state) { //// Log.LogMsg("Testy 13"); try { OwningConnection.SentBytes(state.PacketBufferPointer.Position); bool isUDP = (state.Flags & PacketFlags.UDP) != 0; //Log.LogMsg("==>#### Async SEND Op Completed - #" + ((SockState)args.UserToken).ID.ToString() + "#"); if (args.SocketError == SocketError.Success) { //// Log.LogMsg("Testy 14"); state.PacketBufferPointer.Advance(args.BytesTransferred); if (state.PacketBufferPointer.Position >= state.PacketBuffer.Length) { OwningConnection.PacketSent(); // Done sending packet. state.Reset(); //Log.LogMsg("==>Done sending packet. Sent " + state.PacketBufferPointer.Position.ToString() + " bytes."); // done sending packet, see if we have anything in the queue ready to go bool more = false; Queue<NetQItem> sendQ = isUDP ? m_SendQueueUDP : m_SendQueue; lock (sendQ) { if (sendQ.Count > 0) { NetQItem itm = sendQ.Dequeue(); state.PacketBuffer = itm.Data; state.Flags = itm.Flags; more = true; } else { // release the sending lock if (isUDP) { //Log.LogMsg("UDP send queue emptied."); Interlocked.Exchange(ref m_SendingUDP, 0); } else { //Log.LogMsg("TCP send queue emptied."); Interlocked.Exchange(ref m_Sending, 0); } } } if (more) { //// Log.LogMsg("Testy 15"); SendBuffer(args, state, isUDP); } return; } else { //// Log.LogMsg("Testy 16"); // not done sending. send again. //Log.LogMsg("==>Continuing send. " + state.PacketBufferPointer.Position.ToString() + " / " + state.PacketBuffer.Length.ToString() + " sent so far."); SendBuffer(args, state, isUDP); } } else { //If we are in this else-statement, there was a socket error. OwningConnection.KillConnection("Error sending packet. " + args.SocketError.ToString()); } } catch (Exception ex) { //// Log.LogMsg("Testy 17"); Log.LogMsg("Failed to ProcessSend. " + ex.Message); OwningConnection.KillConnection("Send error. " + ex.Message); } }
public void SendData(ref object data) { byte[] arrData = null; //We store the data here before send it if (m_enmProtocol == ProtocolConstants.sckTCPProtocol) { if (m_enmState != SockState.sckConnected) { Err().Raise(modSocketMaster.sckBadState, "CSocketMaster.SendData", "Wrong protocol or connection state for the requested transaction or request"); return; } //If we use UDP we create a socket if there isn't one yet } else { if (!SocketExists()) return; if (!BindInternal()) return; m_enmState = SockState.sckOpen; Debug.Print("STATE: sckOpen"); } //We need to convert data variant into a byte array string strdata = null; string strArray = null; bool blnData = false; byte bytData = 0; decimal curData = default(decimal); System.DateTime datData = default(System.DateTime); double dblData = 0; short intData = 0; int lngData = 0; float sngData = 0; switch (Information.VarType(data)) { case VariantType.String: strdata = Convert.ToString(data); if (Strings.Len(strdata) == 0) return; arrData = new byte[Strings.Len(strdata)]; arrData = System.Text.UnicodeEncoding.Unicode.GetBytes(strdata); break; case VariantType.Array + VariantType.Byte: strArray = System.Text.Encoding.Unicode.GetString(data); if (Strings.Len(strArray) == 0) return; arrData = System.Text.Encoding.Unicode.GetBytes(strArray); break; case VariantType.Boolean: blnData = Convert.ToBoolean(data); arrData = new byte[modLenB.LenB(blnData)]; modSocketMaster.api_CopyMemory(ref arrData[0], ref blnData, modLenB.LenB(blnData)); break; case VariantType.Byte: bytData = Convert.ToByte(data); arrData = new byte[modLenB.LenB(bytData)]; modSocketMaster.api_CopyMemory(ref arrData[0], ref bytData, modLenB.LenB(bytData)); break; case VariantType.Decimal: curData = Convert.ToDecimal(data); arrData = new byte[modLenB.LenB(curData)]; modSocketMaster.api_CopyMemory(ref arrData[0], ref curData, modLenB.LenB(curData)); break; case VariantType.Date: datData = Convert.ToDateTime(data); arrData = new byte[modLenB.LenB(datData)]; modSocketMaster.api_CopyMemory(ref arrData[0], ref datData, modLenB.LenB(datData)); break; case VariantType.Double: dblData = Convert.ToDouble(data); arrData = new byte[modLenB.LenB(dblData)]; modSocketMaster.api_CopyMemory(ref arrData[0], ref dblData, modLenB.LenB(dblData)); break; case VariantType.Short: intData = Convert.ToInt16(data); arrData = new byte[modLenB.LenB(intData)]; modSocketMaster.api_CopyMemory(ref arrData[0], ref intData, modLenB.LenB(intData)); break; case VariantType.Integer: lngData = Convert.ToInt32(data); arrData = new byte[modLenB.LenB(lngData)]; modSocketMaster.api_CopyMemory(ref arrData[0], ref lngData, modLenB.LenB(lngData)); break; case VariantType.Single: sngData = Convert.ToSingle(data); arrData = new byte[modLenB.LenB(sngData)]; modSocketMaster.api_CopyMemory(ref arrData[0], ref sngData, modLenB.LenB(sngData)); break; default: Err().Raise(modSocketMaster.sckUnsupported, "CSocketMaster.SendData", "Unsupported variant type."); break; } //if there's already something in the buffer that means we are //already sending data, so we put the new data in the buffer //and exit silently if (Strings.Len(m_strSendBuffer) > 0) { m_strSendBuffer = m_strSendBuffer + System.Text.Encoding.Unicode.GetString(arrData); return; } else { m_strSendBuffer = m_strSendBuffer + System.Text.Encoding.Unicode.GetString(arrData); } //send the data SendBufferedData(); }
public void Bind(ref int LocalPort = null, ref string LocalIP = null) { if (m_enmState != SockState.sckClosed) { Err().Raise(modSocketMaster.sckInvalidOp, "CSocketMaster.Bind", "Invalid operation at current state"); } if (BindInternal(LocalPort, LocalIP)) { m_enmState = SockState.sckOpen; Debug.Print("STATE: sckOpen"); } }
//Tries to connect to RemoteHost if it was passed, or uses //m_strRemoteHost instead. If it is a hostname tries to //resolve it first. public void Connect_Renamed(ref string RemoteHost = null, ref int RemotePort = null) { if (m_enmState != SockState.sckClosed) { Err().Raise(modSocketMaster.sckInvalidOp, "CSocketMaster.Connect", "Invalid operation at current state"); } if ((RemoteHost != null)) { m_strRemoteHost = Convert.ToString(RemoteHost); } //for some reason we get a GPF if we try to //resolve a null string, so we replace it with //an empty string if (m_strRemoteHost == Constants.vbNullString) { m_strRemoteHost = ""; } //check if RemotePort is a number between 1 and 65535 if ((RemotePort != null)) { if (Information.IsNumeric(RemotePort)) { if (Convert.ToInt32(RemotePort) > 65535 | Convert.ToInt32(RemotePort) < 1) { Err().Raise(modSocketMaster.sckInvalidArg, "CSocketMaster.Connect", "The argument passed to a function was not in the correct format or in the specified range."); } else { m_lngRemotePort = Convert.ToInt32(RemotePort); } } else { Err().Raise(modSocketMaster.sckUnsupported, "CSocketMaster.Connect", "Unsupported variant type."); } } //create a socket if there isn't one yet if (!SocketExists()) return; //If we are using UDP we just bind the socket and exit //silently. Remember UDP is a connectionless protocol. if (m_enmProtocol == ProtocolConstants.sckUDPProtocol) { if (BindInternal()) { m_enmState = SockState.sckOpen; Debug.Print("STATE: sckOpen"); } return; } //try to get a 32 bits long that is used to identify a host int lngAddress = 0; lngAddress = ResolveIfHostname(m_strRemoteHost, DestResolucion.destConnect); //We've got two options here: //1) m_strRemoteHost was an IP, so a resolution wasn't // necessary, and now lngAddress is a 32 bits long and // we proceed to connect. //2) m_strRemoteHost was a hostname, so a resolution was // necessary and it's taking place right now. We leave // silently. if (lngAddress != VariantType.Null) { ConnectToIP(lngAddress, 0); } }
//Send buffered data if we are using TCP protocol. private void SendBufferedDataTCP() { byte[] arrData = null; int lngBufferLength = 0; int lngResult = 0; int lngTotalSent = 0; int lngErrorCode = 0; bool blnCancelDisplay = false; int lngTemp = 0; while (!(lngResult == modSocketMaster.SOCKET_ERROR | Strings.Len(m_strSendBuffer) == 0)) { lngBufferLength = Strings.Len(m_strSendBuffer); if (lngBufferLength > m_lngSendBufferLen) { lngBufferLength = m_lngSendBufferLen; arrData = System.Text.Encoding.Unicode.GetBytes(Strings.Left(m_strSendBuffer, m_lngSendBufferLen)); } else { arrData = System.Text.Encoding.Unicode.GetBytes(m_strSendBuffer); } lngResult = api_send(m_lngSocketHandle, ref arrData[0], lngBufferLength, 0); if (lngResult == modSocketMaster.SOCKET_ERROR) { lngErrorCode = Err().LastDllError; if (lngErrorCode == modSocketMaster.WSAEWOULDBLOCK) { Debug.Print("WARNING: Send buffer full, waiting..."); if (lngTotalSent > 0) if (SendProgress != null) { SendProgress(lngTotalSent, Strings.Len(m_strSendBuffer)); } } else { m_enmState = SockState.sckError; Debug.Print("STATE: sckError"); blnCancelDisplay = true; if (Error_Renamed != null) { Error_Renamed(lngErrorCode, modSocketMaster.GetErrorDescription(lngErrorCode), 0, "CSocketMaster.SendBufferedData", "", 0, blnCancelDisplay); } if (blnCancelDisplay == false) Interaction.MsgBox(modSocketMaster.GetErrorDescription(lngErrorCode), MsgBoxStyle.OkOnly, "CSocketMaster.SendBufferedData"); } } else { Debug.Print("OK Bytes sent: " + lngResult); lngTotalSent = lngTotalSent + lngResult; if (Strings.Len(m_strSendBuffer) > lngResult) { m_strSendBuffer = Strings.Mid(m_strSendBuffer, lngResult + 1); } else { Debug.Print("OK Finished SENDING"); m_strSendBuffer = ""; lngTemp = lngTotalSent; lngTotalSent = 0; if (SendProgress != null) { SendProgress(lngTemp, 0); } if (SendComplete != null) { SendComplete(); } } } } }
//Tries to create a socket if there isn't one yet and registers //it to the control list. //Returns TRUE if it has success private bool SocketExists() { bool functionReturnValue = false; functionReturnValue = true; int lngResult = 0; int lngErrorCode = 0; //check if there is a socket already bool blnCancelDisplay = false; if (m_lngSocketHandle == modSocketMaster.INVALID_SOCKET) { //decide what kind of socket we are creating, TCP or UDP if (m_enmProtocol == ProtocolConstants.sckTCPProtocol) { lngResult = api_socket(modSocketMaster.AF_INET, modSocketMaster.SOCK_STREAM, modSocketMaster.IPPROTO_TCP); } else { lngResult = api_socket(modSocketMaster.AF_INET, modSocketMaster.SOCK_DGRAM, modSocketMaster.IPPROTO_UDP); } if (lngResult == modSocketMaster.INVALID_SOCKET) { m_enmState = SockState.sckError; Debug.Print("STATE: sckError"); Debug.Print("ERROR trying to create socket"); functionReturnValue = false; lngErrorCode = Err().LastDllError; blnCancelDisplay = true; if (Error_Renamed != null) { Error_Renamed(lngErrorCode, modSocketMaster.GetErrorDescription(lngErrorCode), 0, "CSocketMaster.SocketExists", "", 0, blnCancelDisplay); } if (blnCancelDisplay == false) Interaction.MsgBox(modSocketMaster.GetErrorDescription(lngErrorCode), MsgBoxStyle.OkOnly, "CSocketMaster.SocketExists"); } else { Debug.Print("OK Created socket: " + lngResult); m_lngSocketHandle = lngResult; //set and get some socket options ProcessOptions(); functionReturnValue = modSocketMaster.RegisterSocket(m_lngSocketHandle, VarPtr.VarPtr(this), true); } } return functionReturnValue; }
/// <summary> /// Assembles the packet across however many frames it takes /// </summary> /// <param name="data"></param> public void AssembleInboundPacket(SocketAsyncEventArgs args, SockState state) { AssembleInboundPacket(args.Buffer, args.BytesTransferred, state); }
/// <summary> /// Builds a packet object, given a raw binary buffer and some misc info /// </summary> /// <param name="state"></param> public void DeserializePacket(SockState state) { try { OnPacketReceived(); // at this point, the envelope bytes have been chopped off byte[] body = OnPacketDataArrived(state.PacketBuffer, 0, state.PacketBuffer.Length, state.Flags); if (body == null || body.Length < 1) { KillConnection("Authentication/Encryption Key error."); return; } //Log.LogMsg("Deserializing packet type " + state.PacketTypeID.ToString()); Packet newPacket = CreatePacket(state.PacketTypeID, state.PacketSubTypeID, state.Flags, body); newPacket.PacketSubTypeID = state.PacketSubTypeID; newPacket.RemoteEndPoint = state.AsyncEventArgs.RemoteEndPoint as IPEndPoint; // Send delivery confirmation, check for duplicate packets, etc if (OnBeforePacketProcessed(newPacket)) { // do not ever delay clock sync packets, no matter what. clock sync packets are used to // calculate latencies and to sync game clocks. waiting to respond is not an option, but since // the handler for this packet is deep in the root NetworkConnection hiearchy, it shouldn't // intefere, even with a client that otherwise delays packet handling if (newPacket.PacketTypeID == (int)PacketType.ClockSync) { HandlePacket(newPacket); } // Determine if the packet should be handled immediately or late else if (ProcessIncomingPacketsImmediately) { HandlePacket(newPacket); } else { lock (m_InboxLocker) { m_Inbox.Enqueue(newPacket); } } } } catch (Exception e) { Log.LogMsg("Exception in DeserializePacket: " + e.Message); KillConnection("Deserialize error. " + e.Message); } }
public void SetConState(SockState state) { //Debug.Log("SetconState :" + _state + "--->" + state); _state = state; }
/// <summary> /// 设置状态 /// </summary> /// <param name="state"></param> private void SetSockState(SockState state) { m_State = state; }
public void SetState(SockState state) { m_scoket.SetSockState(state); }
//Send buffered data if we are using UDP protocol. private void SendBufferedDataUDP() { int lngAddress = 0; sockaddr_in udtSockAddr = default(sockaddr_in); byte[] arrData = null; int lngBufferLength = 0; int lngResult = 0; int lngErrorCode = 0; string strTemp = null; lngAddress = ResolveIfHostnameSync(m_strRemoteHost, ref strTemp, ref lngErrorCode); if (lngErrorCode != 0) { m_strSendBuffer = ""; if (lngErrorCode == modSocketMaster.WSAEAFNOSUPPORT) { Err().Raise(lngErrorCode, "CSocketMaster.SendBufferedDataUDP", modSocketMaster.GetErrorDescription(lngErrorCode)); } else { Err().Raise(modSocketMaster.sckInvalidArg, "CSocketMaster.SendBufferedDataUDP", "Invalid argument"); } } var _with3 = udtSockAddr; _with3.sin_addr = lngAddress; _with3.sin_family = modSocketMaster.AF_INET; _with3.sin_port = api_htons(modSocketMaster.UnsignedToInteger(ref ref m_lngRemotePort)); lngBufferLength = Strings.Len(m_strSendBuffer); arrData = System.Text.UnicodeEncoding.Unicode.GetBytes(m_strSendBuffer); m_strSendBuffer = ""; lngResult = api_sendto(m_lngSocketHandle, ref arrData[0], lngBufferLength, 0, ref udtSockAddr, modLenB.LenB(udtSockAddr)); bool blnCancelDisplay = false; if (lngResult == modSocketMaster.SOCKET_ERROR) { lngErrorCode = Err().LastDllError; m_enmState = SockState.sckError; Debug.Print("STATE: sckError"); blnCancelDisplay = true; if (Error_Renamed != null) { Error_Renamed(lngErrorCode, modSocketMaster.GetErrorDescription(lngErrorCode), 0, "CSocketMaster.SendBufferedDataUDP", "", 0, blnCancelDisplay); } if (blnCancelDisplay == false) Interaction.MsgBox(modSocketMaster.GetErrorDescription(lngErrorCode), MsgBoxStyle.OkOnly, "CSocketMaster.SendBufferedDataUDP"); } }
protected virtual void OnInitialize() { LastUDPACKReceived = DateTime.MinValue; m_TCPSockState = new SockState(null, 0, null); m_TCPSockState.AsyncEventArgs = new SocketAsyncEventArgs(); if (!m_IsInitialized) { NetworkConnection.RegisterPacketCreationDelegate((int)PacketType.PacketGenericMessage, delegate { return new PacketGenericMessage(); }); NetworkConnection.RegisterPacketCreationDelegate((int)PacketType.LineSecured, delegate { return new PacketLineSecured(); }); NetworkConnection.RegisterPacketCreationDelegate((int)PacketType.PacketRijndaelExchangeRequest, delegate { return new PacketRijndaelExchangeRequest(); }); NetworkConnection.RegisterPacketCreationDelegate((int)PacketType.PacketGameServerAccessGranted, delegate { return new PacketGameServerTransferResult(); }); NetworkConnection.RegisterPacketCreationDelegate((int)PacketType.LoginRequest, delegate { return new PacketLoginRequest(); }); NetworkConnection.RegisterPacketCreationDelegate((int)PacketType.LoginResult, delegate { return new PacketLoginResult(); }); NetworkConnection.RegisterPacketCreationDelegate((int)PacketType.Null, delegate { return new PacketNull(); }); NetworkConnection.RegisterPacketCreationDelegate((int)PacketType.RequestHandoffToServer, delegate { return new PacketRequestHandoffToServerCluster(); }); NetworkConnection.RegisterPacketCreationDelegate((int)PacketType.RijndaelExchange, delegate { return new PacketRijndaelExchange(); }); NetworkConnection.RegisterPacketCreationDelegate((int)PacketType.PacketStream, delegate { return new PacketStream(); }); NetworkConnection.RegisterPacketCreationDelegate((int)PacketType.CharacterListing, delegate { return new PacketCharacterListing(); }); NetworkConnection.RegisterPacketCreationDelegate((int)PacketType.GenericReply, delegate { return new PacketReply(); }); NetworkConnection.RegisterPacketCreationDelegate((int)PacketType.ACK, delegate { return new PacketACK(); }); NetworkConnection.RegisterPacketCreationDelegate((int)PacketType.NATInfo, delegate { return new PacketNATInfo(); }); NetworkConnection.RegisterPacketCreationDelegate((int)PacketType.ClockSync, delegate { return new PacketClockSync(); }); m_IsInitialized = true; } RegisterPacketHandler((int)PacketType.ACK, OnPacketACK); RegisterPacketHandler((int)PacketType.ClockSync, OnClockSync); RegisterPacketHandler((int)PacketType.PacketStream, ProcessStreamPacket); RegisterPacketHandler((int)PacketType.GenericReply, OnPacketGenericReply); Roles = new string[0]; RegisterPacketHandler((int)PacketType.PacketRijndaelExchangeRequest, OnRijndaelExchangeRequest); RegisterPacketHandler((int)PacketType.LineSecured, OnLineSecured); RegisterPacketHandler((int)PacketType.LoginResult, OnLoginResult); RegisterPacketHandler((int)PacketType.PacketGameServerAccessGranted, OnGameServerAccessInfoArrived); }
public void Accept(ref int requestID) { if (m_enmState != SockState.sckClosed) { Err().Raise(modSocketMaster.sckInvalidOp, "CSocketMaster.Accept", "Invalid operation at current state"); } int lngResult = 0; sockaddr_in udtSockAddr = default(sockaddr_in); int lngErrorCode = 0; m_lngSocketHandle = requestID; m_enmProtocol = ProtocolConstants.sckTCPProtocol; ProcessOptions(); if (!modSocketMaster.IsAcceptRegistered(requestID)) { if (modSocketMaster.IsSocketRegistered(requestID)) { Err().Raise(modSocketMaster.sckBadState, "CSocketMaster.Accept", "Wrong protocol or connection state for the requested transaction or request"); } else { m_blnAcceptClass = true; m_enmState = SockState.sckConnected; Debug.Print("STATE: sckConnected"); //UPGRADE_ISSUE: ObjPtr function is not supported. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="367764E5-F3F8-4E43-AC3E-7FE0B5E074E2"' modSocketMaster.RegisterSocket(m_lngSocketHandle, VarPtr.VarPtr(this), false); return; } } CSocketMaster clsSocket = null; clsSocket = modSocketMaster.GetAcceptClass(requestID); modSocketMaster.UnregisterAccept(requestID); lngResult = api_getsockname(m_lngSocketHandle, ref udtSockAddr, ref modLenB.LenB(udtSockAddr)); if (lngResult == modSocketMaster.SOCKET_ERROR) { lngErrorCode = Err().LastDllError; Err().Raise(lngErrorCode, "CSocketMaster.Accept", modSocketMaster.GetErrorDescription(lngErrorCode)); } else { m_lngLocalPortBind = modSocketMaster.IntegerToUnsigned(ref api_ntohs(udtSockAddr.sin_port)); m_strLocalIP = modSocketMaster.StringFromPointer(api_inet_ntoa(udtSockAddr.sin_addr)); } GetRemoteInfo(m_lngSocketHandle, ref m_lngRemotePort, ref m_strRemoteHostIP, ref m_strRemoteHost); m_enmState = SockState.sckConnected; Debug.Print("STATE: sckConnected"); if (clsSocket.BytesReceived > 0) { clsSocket.GetData(m_strRecvBuffer); } //UPGRADE_ISSUE: ObjPtr function is not supported. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="367764E5-F3F8-4E43-AC3E-7FE0B5E074E2"' modSocketMaster.Subclass_ChangeOwner(requestID, VarPtr.VarPtr(this)); if (Strings.Len(m_strRecvBuffer) > 0) if (DataArrival != null) { DataArrival(Strings.Len(m_strRecvBuffer)); } if (clsSocket.State == SockState.sckClosing) { m_enmState = SockState.sckClosing; Debug.Print("STATE: sckClosing"); if (CloseSck != null) { CloseSck(); } } clsSocket = null; }
/// <summary> /// Gets called when a receive operation resolves. If we were listening for data and the connection /// closed, that also counts as a receive operation resolving. /// </summary> /// <param name="args"></param> private void OnReceiveResolved(bool isUDP, byte[] buffer, int bytesReceived, SocketError status, SockState sockState) { try { if (!IsAlive && bytesReceived > 0) { return; } // If there was a socket error, close the connection. This is NOT a normal // situation, if you get an error here. if (status != SocketError.Success) { if (!ShuttingDown) { KillConnection("Connection lost! Network receive error: " + status); } //Jump out of the ProcessReceive method. return; } m_TCPSockState.AsyncEventArgs.RemoteEndPoint = MyTCPSocket.RemoteEndPoint; // If no data was received, close the connection. This is a NORMAL // situation that shows when the client has finished sending data. if (bytesReceived == 0) { if (!ShuttingDown) { KillConnection("Connection closed by remote host."); } return; } ReceivedBytes(bytesReceived); // restart listening process AssembleInboundPacket(buffer, bytesReceived, sockState); } catch (Exception ex) { Log.LogMsg("Error ProcessReceive. " + ex.Message); KillConnection("Error receive. " + ex.Message); } }
public void CloseSck_Renamed() { if (m_lngSocketHandle == modSocketMaster.INVALID_SOCKET) return; m_enmState = SockState.sckClosing; Debug.Print("STATE: sckClosing"); CleanResolutionSystem(); DestroySocket(); m_lngLocalPortBind = 0; m_strRemoteHostIP = ""; m_strRecvBuffer = ""; m_strSendBuffer = ""; m_lngSendBufferLen = 0; m_lngRecvBufferLen = 0; m_enmState = SockState.sckClosed; Debug.Print("STATE: sckClosed"); }
/// <summary> /// Assembles the packet across however many frames it takes /// </summary> /// <param name="data"></param> public void AssembleInboundPacket(SocketAsyncEventArgs args, SockState state) { throw new NotImplementedException(); }
public void Listen() { if (m_enmState != SockState.sckClosed & m_enmState != SockState.sckOpen) { Err().Raise(modSocketMaster.sckInvalidOp, "CSocketMaster.Listen", "Invalid operation at current state"); } if (!SocketExists()) return; if (!BindInternal()) return; int lngResult = 0; lngResult = api_listen(m_lngSocketHandle, SOMAXCONN); int lngErrorCode = 0; if (lngResult == modSocketMaster.SOCKET_ERROR) { lngErrorCode = Err().LastDllError; Err().Raise(lngErrorCode, "CSocketMaster.Listen", modSocketMaster.GetErrorDescription(lngErrorCode)); } else { m_enmState = SockState.sckListening; Debug.Print("STATE: sckListening"); } }
/// <summary> /// Builds a packet object, given a raw binary buffer and some misc info /// </summary> /// <param name="state"></param> public void DeserializePacket(SockState state) { try { OnPacketReceived(); // at this point, the envelope bytes have been chopped off byte[] body = OnPacketDataArrived(state.PacketBuffer, 0, state.PacketBuffer.Length, state.Flags); if (body == null || body.Length < 1) { KillConnection("Authentication/Encryption Key error."); return; } //Log.LogMsg("Deserializing packet type " + state.PacketTypeID.ToString()); Packet newPacket = CreatePacket(state.PacketTypeID, state.PacketSubTypeID, state.Flags, body); newPacket.PacketSubTypeID = state.PacketSubTypeID; newPacket.RemoteEndPoint = state.AsyncEventArgs.RemoteEndPoint as IPEndPoint; // Send delivery confirmation, check for duplicate packets, etc if (OnBeforePacketProcessed(newPacket)) { HandlePacket(newPacket); } } catch (Exception e) { Log.LogMsg("Exception in DeserializePacket: " + e.Message); KillConnection("Deserialize error. " + e.Message); } }
//ステータスの設定 //Connect/bindで使用する protected void Set(SockState sockState, IPEndPoint localAddress, IPEndPoint remoteAddress) { SockState = sockState; LocalAddress = localAddress; RemoteAddress = remoteAddress; }
//Connect to a given 32 bits long ip private void ConnectToIP(int lngRemoteHostAddress, int lngErrorCode) { bool blnCancelDisplay = false; //Check and handle errors if (lngErrorCode != 0) { m_enmState = SockState.sckError; Debug.Print("STATE: sckError"); blnCancelDisplay = true; if (Error_Renamed != null) { Error_Renamed(lngErrorCode, modSocketMaster.GetErrorDescription(lngErrorCode), 0, "CSocketMaster.ConnectToIP", "", 0, blnCancelDisplay); } if (blnCancelDisplay == false) Interaction.MsgBox(modSocketMaster.GetErrorDescription(lngErrorCode), MsgBoxStyle.OkOnly, "CSocketMaster.ConnectToIP"); return; } //Here we bind the socket if (!BindInternal()) return; Debug.Print("OK Connecting to: " + m_strRemoteHost + " " + m_strRemoteHostIP); m_enmState = SockState.sckConnecting; Debug.Print("STATE: sckConnecting"); //UPGRADE_WARNING: Arrays in structure udtSockAddr may need to be initialized before they can be used. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="814DF224-76BD-4BB4-BFFB-EA359CB9FC48"' sockaddr_in udtSockAddr = default(sockaddr_in); int lngResult = 0; //Build the sockaddr_in structure to pass it to the connect //Winsock API function as an address of the remote host. var _with1 = udtSockAddr; _with1.sin_addr = lngRemoteHostAddress; _with1.sin_family = modSocketMaster.AF_INET; _with1.sin_port = api_htons(modSocketMaster.UnsignedToInteger(ref ref m_lngRemotePort)); //Call the connect Winsock API function in order to establish connection. //UPGRADE_ISSUE: LenB function is not supported. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="367764E5-F3F8-4E43-AC3E-7FE0B5E074E2"' lngResult = api_connect(m_lngSocketHandle, ref udtSockAddr, modLenB.LenB(udtSockAddr)); //Check and handle errors if (lngResult == modSocketMaster.SOCKET_ERROR) { lngErrorCode = Err().LastDllError; if (lngErrorCode != modSocketMaster.WSAEWOULDBLOCK) { if (lngErrorCode == modSocketMaster.WSAEADDRNOTAVAIL) { Err().Raise(modSocketMaster.WSAEADDRNOTAVAIL, "CSocketMaster.ConnectToIP", modSocketMaster.GetErrorDescription(modSocketMaster.WSAEADDRNOTAVAIL)); } else { m_enmState = SockState.sckError; Debug.Print("STATE: sckError"); blnCancelDisplay = true; if (Error_Renamed != null) { Error_Renamed(lngErrorCode, modSocketMaster.GetErrorDescription(lngErrorCode), 0, "CSocketMaster.ConnectToIP", "", 0, blnCancelDisplay); } if (blnCancelDisplay == false) Interaction.MsgBox(modSocketMaster.GetErrorDescription(lngErrorCode), MsgBoxStyle.OkOnly, "CSocketMaster.ConnectToIP"); } } } }
protected void SetError(String msg) { _lastError = msg; SockState = SockState.Error; }
//Destroys the socket if it exists and unregisters it //from control list. private void DestroySocket() { int lngResult = 0; int lngErrorCode = 0; if (!(m_lngSocketHandle == modSocketMaster.INVALID_SOCKET)) { lngResult = api_closesocket(m_lngSocketHandle); if (lngResult == modSocketMaster.SOCKET_ERROR) { m_enmState = SockState.sckError; Debug.Print("STATE: sckError"); lngErrorCode = Err().LastDllError; Err().Raise(lngErrorCode, "CSocketMaster.DestroySocket", modSocketMaster.GetErrorDescription(lngErrorCode)); } else { Debug.Print("OK Destroyed socket " + m_lngSocketHandle); modSocketMaster.UnregisterSocket(m_lngSocketHandle); m_lngSocketHandle = modSocketMaster.INVALID_SOCKET; } } }
/// <summary> /// We dont usually send everything all at once in the buffer. This method sends what's in the buffer out in a piece by piece fashion. /// </summary> private void SendBuffer(SocketAsyncEventArgs args, SockState state, bool isUDP) { try { #if !SILVERLIGHT //Log.LogMsg("==>$$$$ Async SEND op started - #" + ((SockState)args.UserToken).ID.ToString() + "#"); if (!OwningConnection.BlockingMode) #endif { int toSend = state.PacketBuffer.Length - state.PacketBufferPointer.Position; if (toSend > state.BufferBlockLength) { toSend = state.BufferBlockLength; } args.SetBuffer(state.BufferBlockOffset, toSend); Util.Copy(state.PacketBuffer, state.PacketBufferPointer.Position, args.Buffer, state.BufferBlockOffset, toSend); Socket socket = OwningConnection.MyTCPSocket; #if !SILVERLIGHT if (isUDP) { socket = OwningConnection.MyUDPSocket; //Log.LogMsg("UDP Send Target = " + SendTarget.ToString()); args.RemoteEndPoint = OwningConnection.UDPSendTarget; if (!socket.SendToAsync(args)) { //// Log.LogMsg("Testy 7"); OnSendResolved(args, state); } } else #endif { if (!socket.SendAsync(args)) { //// Log.LogMsg("Testy 8"); OnSendResolved(args, state); } } } #if !SILVERLIGHT else { if (isUDP) { //// Log.LogMsg("Testy 9"); OwningConnection.MyUDPSocket.SendTo(state.PacketBuffer, OwningConnection.UDPSendTarget); } else { //// Log.LogMsg("Testy 10"); OwningConnection.MyTCPSocket.Blocking = true; OwningConnection.MyTCPSocket.Send(state.PacketBuffer); } //// Log.LogMsg("Testy 11"); OwningConnection.SentBytes(state.PacketBuffer); OwningConnection.PacketSent(); } #endif } catch (Exception e) { //// Log.LogMsg("Testy 12"); Log.LogMsg("Error SendBuffer. " + e.Message); OwningConnection.KillConnection("Send error. " + e.Message); } }
//When the system resolves a hostname in asynchronous way we //call this function to decide what to do with the result. private void PostResolution(int lngAsynHandle, int lngErrorCode) { if (m_enmState != SockState.sckResolvingHost) return; DestResolucion enmDestination = default(DestResolucion); //find out what the resolution destination was //UPGRADE_WARNING: Couldn't resolve default property of object m_colWaitingResolutions.Item(). Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"' enmDestination = m_colWaitingResolutions["R" + lngAsynHandle]; //erase that record from the collection since we won't need it any longer m_colWaitingResolutions.Remove("R" + lngAsynHandle); HOSTENT udtHostent = default(HOSTENT); int lngPtrToIP = 0; int lngRemoteHostAddress = 0; short Count = 0; string strIpAddress = null; //UPGRADE_WARNING: Lower bound of array arrIpAddress was changed from 1 to 0. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="0F1C9BE1-AF9D-476E-83B1-17D43BECFF20"' byte[] arrIpAddress = new byte[5]; //if there weren't errors trying to resolve the hostname if (lngErrorCode == 0) { m_enmState = SockState.sckHostResolved; Debug.Print("STATE: sckHostResolved"); //UPGRADE_ISSUE: LenB function is not supported. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="367764E5-F3F8-4E43-AC3E-7FE0B5E074E2"' //UPGRADE_WARNING: Couldn't resolve default property of object udtHostent. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"' modSocketMaster.api_CopyMemory(ref udtHostent, ref m_lngMemoryPointer, modLenB.LenB(udtHostent)); modSocketMaster.api_CopyMemory(ref lngPtrToIP, ref udtHostent.hAddrList, 4); modSocketMaster.api_CopyMemory(ref arrIpAddress[1], ref lngPtrToIP, 4); modSocketMaster.api_CopyMemory(ref lngRemoteHostAddress, ref lngPtrToIP, 4); //free memmory, won't need it any longer FreeMemory(); //We turn the 32 bits long into a readable string. //Note: we don't need this string. I put this here just //in case you need it. for (Count = 1; Count <= 4; Count++) { strIpAddress = strIpAddress + arrIpAddress[Count] + "."; } strIpAddress = Strings.Left(strIpAddress, Strings.Len(strIpAddress) - 1); //Decide what to do with the result according to the destination switch (enmDestination) { case DestResolucion.destConnect: ConnectToIP(lngRemoteHostAddress, 0); break; } //there were errors trying to resolve the hostname } else { //free buffer memory FreeMemory(); switch (enmDestination) { case DestResolucion.destConnect: ConnectToIP(VariantType.Null, lngErrorCode); break; } } }
//This procedure is called by the WindowProc callback function //from the modSocketMaster module. The lngEventID argument is an //ID of the network event occurred for the socket. The lngErrorCode //argument contains an error code only if an error was occurred //during an asynchronous execution. private void PostSocket(int lngEventID, int lngErrorCode) { //handle any possible error bool blnCancelDisplay = false; if (lngErrorCode != 0) { m_enmState = SockState.sckError; Debug.Print("STATE: sckError"); blnCancelDisplay = true; if (Error_Renamed != null) { Error_Renamed(lngErrorCode, modSocketMaster.GetErrorDescription(lngErrorCode), 0, "CSocketMaster.PostSocket", "", 0, blnCancelDisplay); } if (blnCancelDisplay == false) Interaction.MsgBox(modSocketMaster.GetErrorDescription(lngErrorCode), MsgBoxStyle.OkOnly, "CSocketMaster.PostSocket"); return; } //UPGRADE_WARNING: Arrays in structure udtSockAddr may need to be initialized before they can be used. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="814DF224-76BD-4BB4-BFFB-EA359CB9FC48"' sockaddr_in udtSockAddr = default(sockaddr_in); int lngResult = 0; int lngBytesReceived = 0; int lngTempRP = 0; string strTempRHIP = null; string strTempRH = null; switch (lngEventID) { //====================================================================== case modSocketMaster.FD_CONNECT: //Arrival of this message means that the connection initiated by the call //of the connect Winsock API function was successfully established. Debug.Print("FD_CONNECT " + m_lngSocketHandle); if (m_enmState != SockState.sckConnecting) { Debug.Print("WARNING: Omitting FD_CONNECT"); return; } //Get the connection local end-point parameters //UPGRADE_ISSUE: LenB function is not supported. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="367764E5-F3F8-4E43-AC3E-7FE0B5E074E2"' lngResult = api_getpeername(m_lngSocketHandle, ref udtSockAddr, ref modLenB.LenB(udtSockAddr)); if (lngResult == 0) { m_lngRemotePort = modSocketMaster.IntegerToUnsigned(ref api_ntohs(udtSockAddr.sin_port)); m_strRemoteHostIP = modSocketMaster.StringFromPointer(api_inet_ntoa(udtSockAddr.sin_addr)); } m_enmState = SockState.sckConnected; Debug.Print("STATE: sckConnected"); if (Connect != null) { Connect(); } break; //====================================================================== case modSocketMaster.FD_WRITE: //This message means that the socket in a write-able //state, that is, buffer for outgoing data of the transport //service is empty and ready to receive data to send through //the network. Debug.Print("FD_WRITE " + m_lngSocketHandle); if (m_enmState != SockState.sckConnected) { Debug.Print("WARNING: Omitting FD_WRITE"); return; } if (Strings.Len(m_strSendBuffer) > 0) { SendBufferedData(); } break; //====================================================================== case modSocketMaster.FD_READ: //Some data has arrived for this socket. Debug.Print("FD_READ " + m_lngSocketHandle); if (m_enmProtocol == ProtocolConstants.sckTCPProtocol) { if (m_enmState != SockState.sckConnected) { Debug.Print("WARNING: Omitting FD_READ"); return; } //Call the RecvDataToBuffer function that move arrived data //from the Winsock buffer to the local one and returns number //of bytes received. lngBytesReceived = RecvDataToBuffer(); if (lngBytesReceived > 0) { if (DataArrival != null) { DataArrival(Strings.Len(m_strRecvBuffer)); } } //UDP protocol } else { if (m_enmState != SockState.sckOpen) { Debug.Print("WARNING: Omitting FD_READ"); return; } //If we use UDP we don't remove data from winsock buffer. //We just let the user know the amount received so //he/she can decide what to do. lngBytesReceived = GetBufferLenUDP(); if (lngBytesReceived > 0) { if (DataArrival != null) { DataArrival(lngBytesReceived); } } //Now the buffer is emptied no matter what the user //dicided to do with the received data EmptyBuffer(); } break; //====================================================================== case modSocketMaster.FD_ACCEPT: //When the socket is in a listening state, arrival of this message //means that a connection request was received. Call the accept //Winsock API function in oreder to create a new socket for the //requested connection. Debug.Print("FD_ACCEPT " + m_lngSocketHandle); if (m_enmState != SockState.sckListening) { Debug.Print("WARNING: Omitting FD_ACCEPT"); return; } //UPGRADE_ISSUE: LenB function is not supported. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="367764E5-F3F8-4E43-AC3E-7FE0B5E074E2"' lngResult = api_accept(m_lngSocketHandle, ref udtSockAddr, ref modLenB.LenB(udtSockAddr)); if (lngResult == modSocketMaster.INVALID_SOCKET) { lngErrorCode = Err().LastDllError; Err().Raise(lngErrorCode, "CSocketMaster.PostSocket", modSocketMaster.GetErrorDescription(lngErrorCode)); } else { //We assign a temporal instance of CSocketMaster to //handle this new socket until user accepts (or not) //the new connection modSocketMaster.RegisterAccept(lngResult); //We change remote info before firing ConnectionRequest //event so the user can see which host is trying to //connect. lngTempRP = m_lngRemotePort; strTempRHIP = m_strRemoteHostIP; strTempRH = m_strRemoteHost; GetRemoteInfo(lngResult, ref m_lngRemotePort, ref m_strRemoteHostIP, ref m_strRemoteHost); Debug.Print("OK Accepted socket: " + lngResult); if (ConnectionRequest != null) { ConnectionRequest(lngResult); } //we return original info if (m_enmState == SockState.sckListening) { m_lngRemotePort = lngTempRP; m_strRemoteHostIP = strTempRHIP; m_strRemoteHost = strTempRH; } //This is very important. If the connection wasn't accepted //we must close the socket. if (modSocketMaster.IsAcceptRegistered(lngResult)) { api_closesocket(lngResult); modSocketMaster.UnregisterSocket(lngResult); modSocketMaster.UnregisterAccept(lngResult); Debug.Print("OK Closed accepted socket: " + lngResult); } } break; //====================================================================== case modSocketMaster.FD_CLOSE: //This message means that the remote host is closing the conection Debug.Print("FD_CLOSE " + m_lngSocketHandle); if (m_enmState != SockState.sckConnected) { Debug.Print("WARNING: Omitting FD_CLOSE"); return; } m_enmState = SockState.sckClosing; Debug.Print("STATE: sckClosing"); if (CloseSck != null) { CloseSck(); } break; } }
//This function retrieves data from the Winsock buffer //into the class local buffer. The function returns number //of bytes retrieved (received). private int RecvDataToBuffer() { int functionReturnValue = 0; byte[] arrBuffer = null; int lngBytesReceived = 0; string strBuffTemporal = null; arrBuffer = new byte[m_lngRecvBufferLen]; lngBytesReceived = api_recv(m_lngSocketHandle, ref arrBuffer[0], m_lngRecvBufferLen, 0); int lngErrorCode = 0; if (lngBytesReceived == modSocketMaster.SOCKET_ERROR) { m_enmState = SockState.sckError; Debug.Print("STATE: sckError"); lngErrorCode = Err().LastDllError; Err().Raise(lngErrorCode, "CSocketMaster.RecvDataToBuffer", modSocketMaster.GetErrorDescription(lngErrorCode)); } else if (lngBytesReceived > 0) { strBuffTemporal = System.Text.Encoding.Unicode.GetString(arrBuffer); m_strRecvBuffer = m_strRecvBuffer + Strings.Left(strBuffTemporal, lngBytesReceived); functionReturnValue = lngBytesReceived; } return functionReturnValue; }
/// <summary> /// Gets called when a receive operation resolves. If we were listening for data and the connection /// closed, that also counts as a receive operation resolving. /// </summary> /// <param name="args"></param> private void OnReceiveResolved(bool isUDP, byte[] buffer, int bytesReceived, SocketError status, SockState sockState) { SocketDebug(10); //// Log.LogMsg("==>++++ Async RECEIVE Op Completed - #" + ((SockState)args.UserToken).ID.ToString() + "#"); try { if (!OwningConnection.IsAlive && bytesReceived > 0) { return; } // If there was a socket error, close the connection. This is NOT a normal // situation, if you get an error here. if (status != SocketError.Success) { if (!OwningConnection.ShuttingDown) { SocketDebug(11); OwningConnection.KillConnection("Connection lost! Network receive error: " + status); } //Jump out of the ProcessReceive method. return; } SocketDebug(12); m_TCPSockState.AsyncEventArgs.RemoteEndPoint = OwningConnection.MyTCPSocket.RemoteEndPoint; // If no data was received, close the connection. This is a NORMAL // situation that shows when the client has finished sending data. if (bytesReceived == 0) { if (!OwningConnection.ShuttingDown) { OwningConnection.KillConnection("Connection closed by remote host."); } return; } OwningConnection.ReceivedBytes(bytesReceived); // restart listening process OwningConnection.AssembleInboundPacket(buffer, bytesReceived, sockState); } catch (ThreadAbortException abort) { } catch (Exception ex) { Log.LogMsg("Error ProcessReceive. " + ex.Message); OwningConnection.KillConnection("Error receive. " + ex.Message); } }