// 게임 서버와의 비동기 접속이 끝났을 경우 호출되는 콜백 메소드. private void OnConnectSuccess(IAsyncResult asyncResult) { try { // 접속이 완료되었으므로 Connect 요청을 그만 둠. socket.EndConnect(asyncResult); IsConnected = true; Debug.LogFormat("Server connect success ip {0}, port {1}", Ip, Port); } catch (Exception e) { Debug.Log("Socket connect callback function failed : " + e.Message); return; } var recvData = new AsyncRecvData(NetworkDefinition.BufferSize, socket); // 연결된 소켓에 Recv를 걸어준다. socket.BeginReceive( recvData.Buffer, // 버퍼 0, // 받은 데이터를 저장할 zero-base postion recvData.Buffer.Length, // 버퍼 길이 SocketFlags.None, // SocketFlags, 여기서는 None을 지정한다. recvCallBack, // Recv IO가 끝난 뒤 호출할 메소드. recvData // IO가 끝난 뒤 호출할 메소드의 인자로 들어갈 사용자 구조체. ); }
// 비동기 접속이 끝났을 경우 호출되는 콜백 메소드. void OnConnectSuccess(IAsyncResult asyncResult) { try { // 접속이 완료되었으므로 Connect 요청을 그만둠. _socket.EndConnect(asyncResult); _isConnected = true; Debug.LogFormat("Server Connect Success Ip {0}, Port : {1}", _ipAddress, _port); } catch (Exception e) { Debug.Log("Socket Connect Callback Function failed : " + e.Message); return; } // 연결된 소켓에 Recv를 걸어준다. var recvData = new AsyncRecvData(NetworkDefinition.BufferSize, _socket); _socket.BeginReceive( recvData._buffer, // 버퍼 0, // 받은 데이터를 저장할 zero-base postion recvData._buffer.Length, // 버퍼 길이 SocketFlags.None, // SocketFlags, 여기서는 None을 지정한다. _recvCallback, // Recv IO가 끝난 뒤 호출할 메소드. recvData // IO가 끝난 뒤 호출할 메소드의 인자로 들어갈 사용자 구조체. ); }
void ConnectCallback(IAsyncResult asyncResult) { try { socket.EndConnect(asyncResult); isConnected = true; } catch { return; } AsyncRecvData asyncRecvData = new AsyncRecvData(bufferSize, socket); socket.BeginReceive( asyncRecvData.buffer, 0, asyncRecvData.buffer.Length, SocketFlags.None, recvCallback, asyncRecvData); }
void RecvCallback(IAsyncResult asyncResult) { if (isConnected == false) { return; } AsyncRecvData asyncRecvData = (AsyncRecvData)asyncResult.AsyncState; try { asyncRecvData.recvNum += asyncRecvData.socket.EndReceive(asyncResult); asyncRecvData.readPos = 0; } catch (SocketException except) { ProcessException(except); return; } //성능 이슈로 포인터 기반으로 동작하게 고침 #region make packet while (true) { if (asyncRecvData.recvNum < NetworkConstants.PACKET_HEADER_SIZE) { break; } unsafe { //패킷 헤더의 위치를 가리키는 포인터를 선언한다. fixed(byte *packetHeaderPos = &asyncRecvData.buffer[asyncRecvData.readPos]) { //해당 위치에서 PacketHeader를 읽는다 PacketHeader *packetHeader = (PacketHeader *)packetHeaderPos; int packetSize = NetworkConstants.PACKET_HEADER_SIZE + packetHeader->bodySize; if (asyncRecvData.recvNum < packetSize) { break; } Packet packet = new Packet(); packet.bodySize = packetHeader->bodySize; packet.pktId = packetHeader->pktId; packet.data = NetworkConstants.ENCODING.GetString( asyncRecvData.buffer, asyncRecvData.readPos + NetworkConstants.PACKET_HEADER_SIZE, packetHeader->bodySize); lock (this) { packetQueue.Enqueue(packet); } asyncRecvData.readPos += packetSize; asyncRecvData.recvNum -= packetSize; } } } #endregion #region shift remain bytes to front for (int i = 0; i < asyncRecvData.recvNum; i++) { asyncRecvData.buffer[i] = asyncRecvData.buffer[asyncRecvData.readPos + i]; } #endregion asyncRecvData.socket.BeginReceive( asyncRecvData.buffer, asyncRecvData.recvNum, asyncRecvData.buffer.Length - asyncRecvData.recvNum, SocketFlags.None, recvCallback, asyncRecvData); }