void SendCallback(IAsyncResult asyncResult) { if (isConnected == false) { return; } AsyncSendData asyncSendData = (AsyncSendData)asyncResult; int sendNum = 0; try { sendNum = asyncSendData.socket.EndSend(asyncResult); } catch (SocketException except) { ProcessException(except); return; } if (sendNum < asyncSendData.sendNum) { socket.BeginSend( asyncSendData.buffer, sendNum, asyncSendData.buffer.Length - sendNum, SocketFlags.Truncated, sendCallback, asyncSendData); } }
/// <summary> /// 发送数据 /// </summary> /// <param name="state">参数</param> private void SendData(object state) { AsyncSendData asyncSendData = state as AsyncSendData; if (asyncSendData != null) { this.Send(asyncSendData.Data, asyncSendData.Offset, asyncSendData.Size); asyncSendData.Callback?.Invoke(asyncSendData.State); } }
/// <summary> /// 异步发送请求 /// </summary> /// <param name="data">数据</param> /// <param name="callback">回调函数</param> /// <param name="offset">offset</param> /// <param name="size">size</param> /// <param name="state">参数</param> public void AsyncSend(byte[] data, WaitCallback callback, int offset, int size, object state) { AsyncSendData state2 = new AsyncSendData { Callback = callback, Data = data, Offset = offset, Size = size, State = state }; ThreadPool.QueueUserWorkItem(this.SendData, state2); }
/// <summary> /// constructor. takes the async data blob /// </summary> /// <param name="data">async data to constructor</param> internal AsyncOperationCompletedEventArgs(AsyncData data) : base(data.Exception, false, data.UserData) { feedObject = data.Feed; stream = data.DataStream; AsyncSendData sData = data as AsyncSendData; if (sData != null) { entryObject = sData.Entry; } }
// 게임 서버에게 요청한 패킷을 보내주는 메소드. public void SendPacket <T>(T data, PacketId packetId) { if (IsConnected == false) { Debug.LogAssertion("Socket connection not completed yet"); return; } var sendData = new AsyncSendData(socket); var messageBytes = MessagePackSerializer.Serialize(data); var header = new PacketHeader() { PacketId = (int)packetId, BodySize = messageBytes.Length }; var headerBytes = MessagePackSerializer.Serialize(header); sendData.Buffer = new byte[headerBytes.Length + messageBytes.Length]; Array.Copy(headerBytes, 0, sendData.Buffer, 0, headerBytes.Length); Array.Copy(messageBytes, 0, sendData.Buffer, headerBytes.Length, messageBytes.Length); try { // 비동기 전송 시작. 파라미터는 BeginReceive와 대동소이하므로 생략. socket.BeginSend( sendData.Buffer, 0, NetworkDefinition.PacketHeaderSize + messageBytes.Length, SocketFlags.None, sendCallBack, sendData); } catch (SocketException e) { HandleException(e); return; } }
// 지정한 구조체를 패킷으로 만들어 서버에 전달하는 메소드. public void SendPacket <T>(T data, PacketId packetId) { if (_isConnected == false) { Debug.LogAssertion("Socket Connection Not Completed"); return; } var sendData = new AsyncSendData(_socket); int id; int bodySize; // 포인터 동작 수행. unsafe { #region PREPARE SENDING DATAS // 보낼 데이터 구조체를 Json 형태로 바꿔줌. string jsonData = JsonUtility.ToJson(data); id = (int)packetId; bodySize = jsonData.Length + 1; // Send 버퍼 생성. sendData._buffer = new byte[NetworkDefinition.PacketHeaderSize + bodySize + 1]; sendData._sendSize = NetworkDefinition.PacketHeaderSize + bodySize; #endregion #region COPYING PACKET HEADER // 패킷 아이디 주소의 첫 번째 자리. byte *packetIdPos = (byte *)&id; // 포인터를 옮겨가며 버퍼에 기록. for (int i = 0; i < NetworkDefinition.IntSize; ++i) { sendData._buffer[i] = packetIdPos[i]; } // 패킷 바디사이즈 주소의 첫 번째 자리. byte *bodySizePos = (byte *)&bodySize; // 아이디를 기록했던 버퍼 자리 뒤부터 기록. for (int i = 0; i < NetworkDefinition.IntSize; ++i) { sendData._buffer[NetworkDefinition.IntSize + i] = bodySizePos[i]; } #endregion #region COPYING PACKET BODY // 패킷 바디 주소의 첫 번째 자리. char[] bodyPos = jsonData.ToCharArray(); // 헤더를 기록했던 버퍼 자리 뒤부터 기록. for (int i = 0; i < bodySize - 1; ++i) { sendData._buffer[NetworkDefinition.PacketHeaderSize + i] = (byte)bodyPos[i]; } // 뒤에 널 문자 추가. var nullChar = Convert.ToByte('\0'); sendData._buffer[NetworkDefinition.PacketHeaderSize + bodySize] = nullChar; #endregion ; } try { // 비동기 전송 시작. 파라미터는 BeginReceive와 대동소이하므로 생략. _socket.BeginSend( sendData._buffer, 0, NetworkDefinition.PacketHeaderSize + bodySize, SocketFlags.None, _sendCallback, sendData); } catch (SocketException e) { HandleException(e); return; } }
public void SendPacket <T>(T data, PacketId pktId) { if (isConnected == false) { return; } AsyncSendData asyncSendData = new AsyncSendData(socket); //성능 이슈로 포인터 기반으로 동작하게 바꿈 unsafe { #region prepare datas for copying to send buffer string jsonedData = JsonUtility.ToJson(data); int packetId = (int)pktId; int bodySize = jsonedData.Length; asyncSendData.buffer = new byte[NetworkConstants.PACKET_HEADER_SIZE + bodySize]; asyncSendData.sendNum = NetworkConstants.PACKET_HEADER_SIZE + bodySize; #endregion #region copy packet id to send buffer byte *packetIdPos = (byte *)&packetId; for (int i = 0; i < NetworkConstants.INT_SIZE; i++) { asyncSendData.buffer[i] = packetIdPos[i]; } #endregion #region copy body size to send buffer byte *bodySizePos = (byte *)&bodySize; for (int i = 0; i < NetworkConstants.INT_SIZE; i++) { asyncSendData.buffer[i + NetworkConstants.INT_SIZE] = bodySizePos[i]; } #endregion #region copy body to send buffer char[] bodyPos = jsonedData.ToCharArray(); for (int i = 0; i < bodySize; i++) { asyncSendData.buffer[i + NetworkConstants.PACKET_HEADER_SIZE] = (byte)bodyPos[i]; } #endregion } try { socket.BeginSend( asyncSendData.buffer, 0, asyncSendData.buffer.Length, SocketFlags.None, sendCallback, asyncSendData); } catch (SocketException except) { ProcessException(except); return; } }