private void EndReceive(IAsyncResult asyncResult) { try { // This will contain the client's endpoint. EndPoint senderEndPoint = new IPEndPoint(IPAddress.Any, 0); // Receive all data. var bytesReceived = _serverSocket.EndReceiveFrom(asyncResult, ref senderEndPoint); var state = asyncResult.AsyncState as StateObject; state.EndPoint = senderEndPoint; state.DataStream.AddRange(state.Data.Take(bytesReceived)); Array.Clear(state.Data, 0, state.Data.Length); var packetData = state.DataStream.ToArray(); var packetSize = BitConverter.ToInt32(packetData, 0); if (packetSize == packetData.Length) { var receivedData = Packet.Deserialize(packetData) as ChatPacket; Packets.HandlePacket(senderEndPoint, receivedData); state.DataStream.Clear(); // Listen for more connections. BeginReceive(senderEndPoint); } else { // If the packet size doesn't equal the packet length, we will keep receiving more data until it does. _serverSocket.BeginReceiveFrom(state.Data, 0, state.Data.Length, SocketFlags.None, ref senderEndPoint, EndReceive, state); } } catch (Exception ex) { Logger.WriteLine(ex); } }
//이 쓰레드가 클라이언트로부터 계속해서 메시지를 받는 쓰레드. 각 클라이언트 수 만큼 서버는 이 쓰레드를 돌림 private void doChat() { NetworkStream stream = null; try { byte[] readbuffer = new byte[1024 * 4]; int bytes = 0; int MessageCount = 0; int cli_num = 0; while (true) //클라이언트로부터 메시지 받는 것을 계속 대기중 { MessageCount++; try { stream = clientSocket.GetStream(); //클라이언트 소켓 받고 bytes = stream.Read(this.readbuffer, 0, this.readbuffer.Length); //읽음 Packet packet = (Packet)Packet.Deserialize(this.readbuffer); cli_num = clientNum[clientSocket]; if (OnRequest != null) { OnRequest(packet.Type, this.readbuffer, cli_num); } } catch (Exception e) { MessageBox.Show(e.Message + e.StackTrace); } } } catch (SocketException se) { Trace.WriteLine(string.Format("doChat - SocketException : {0}", se.Message)); if (clientSocket != null) { if (OnDisconnected != null) { OnDisconnected(clientSocket); } clientSocket.Close(); stream.Close(); } } catch (Exception ex) { Trace.WriteLine(string.Format("doChat - Exception : {0}", ex.Message)); if (clientSocket != null) { if (OnDisconnected != null) { OnDisconnected(clientSocket); } clientSocket.Close(); stream.Close(); } } }
private void InitSocket() { server = new TcpListener(IPAddress.Any, 9999); clientSocket = default(TcpClient); server.Start(); DisplayText(">> Server Start!! <<"); while (true) {//클라이언트 요청 받음 -> 소켓과 닉네임 저장 try { clientSocket = server.AcceptTcpClient(); clientNum.Add(clientSocket, counter); fileStrm = new FileStream(Environment.CurrentDirectory + "\\Server\\bin\\Debug\\" + counter.ToString() + ".jpg", FileMode.Create, FileAccess.Write); counter++; //클라이언트 수 추가 DisplayText(">> Accept connection from client"); ///////////////////////////////// 닉네임 저장 //////////////////////////////// ClientProfile clientProfile = new ClientProfile(); //패킷을 위한 객체 stream = clientSocket.GetStream(); int bytes = stream.Read(this.readbuffer, 0, this.readbuffer.Length); string nickName = null; Packet packet = (Packet)Packet.Deserialize(this.readbuffer); clientProfile = (ClientProfile)Packet.Deserialize(this.readbuffer); nickName = clientProfile.nickName; clientList.Add(clientSocket, nickName); //클라이언트 리스트에 새로 접속한 클라이언트 소켓과 닉네임 저장 clients.Add(clientSocket); nickNameList.Add(nickName); clientScore.Add(counter - 1, 0); ////////////////////////////////////////////////////////////////////////////////// ///////// 새로 접속한 클라이언트에게 클라이언트 넘버 및 기존 닉네임들 전송 ///////// Init init = new Init(); init.clinetNumber = clientNum[clientSocket]; init.Type = (int)PacketType.초기화; for (int i = 0; i <= clientNum[clientSocket]; i++) { init.nickNameList[i] = (string)nickNameList[i]; } Packet.Serialize(init).CopyTo(this.sendbuffer, 0); stream.Write(this.sendbuffer, 0, this.sendbuffer.Length); stream.Flush(); resetBuffer(sendbuffer); /////////////////////////////////////////////////////////////////////////////////////// /*닉네임 추가 -> 라벨 추가하기 위해서 6.13 */ foreach (var pair in clientList) { TcpClient client = pair.Key as TcpClient; NickName nick_name = new NickName(); nick_name.client_sum = counter; //추가된 클라이언트수 nick_name.Type = (int)PacketType.닉네임; for (int i = 0; i <= clientNum[clientSocket]; i++) { nick_name.nickNameList[i] = (string)nickNameList[i]; } NetworkStream stream = client.GetStream(); Packet.Serialize(nick_name).CopyTo(this.sendbuffer, 0); stream.Write(this.sendbuffer, 0, this.sendbuffer.Length); this.stream.Flush(); resetBuffer(sendbuffer); } // send message all user SendMessageAll(nickName + "님이 접속하셨습니다.", "", false); //서버한테 //handleClient클래스는 클라이언트들을 다루는 클래스 handleClient h_client = new handleClient(); h_client.OnRequest += new handleClient.ClientRequestHandler(this.OnRequest); //클라이언트 요청 이벤트 핸들러 추가. h_client.OnDisconnected += new handleClient.DisconnectedHandler(h_client_OnDisconnected); //연결 끊겼을 때 h_client.startClient(clientSocket, clientList, clientNum); } catch (SocketException se) //소켓 연결에서의 예외 발생 { Trace.WriteLine(string.Format("InitSocket - SocketException : {0}", se.Message)); break; } catch (Exception ex) //그 외의 예외 발생 { Trace.WriteLine(string.Format("InitSocket - Exception : {0}", ex.Message)); break; } } clientSocket.Close(); server.Stop(); }
private void OnRequest(int requestType, byte[] readBuffer, int cli_num) { //클라이언트의 리퀘스트 타입을 식별하여 타입에 알맞게 처리 switch (requestType) { case (int)PacketType.메세지: { ClientMessage clientMessage = new ClientMessage(); clientMessage = (ClientMessage)Packet.Deserialize(readBuffer); msgReceived(clientMessage.Message, clientMessage.nickName); break; } case (int)PacketType.프로필: { ClientProfile clientProfile = new ClientProfile(); clientProfile = (ClientProfile)Packet.Deserialize(readBuffer); profileReceived(clientProfile.nickName, clientProfile.buffer, clientProfile.count, cli_num); break; } case (int)PacketType.게임상태: { GameState statePacket = new GameState(); statePacket = (GameState)Packet.Deserialize(readBuffer); stateReceived(statePacket.gameStart); break; } case (int)PacketType.랭킹: { Ranking rank = new Ranking(); rank = (Ranking)Packet.Deserialize(readBuffer); SendScoreAll(); break; } case (int)PacketType.정답: { TurnChange turnPacket = new TurnChange(); turnPacket = (TurnChange)Packet.Deserialize(readBuffer); DisplayText("Turn Change" + turnPacket.turn.ToString()); answerReceived(turnPacket.turn, turnPacket.score, turnPacket.message, turnPacket.clientNum); break; } case (int)PacketType.그림정보: { ClientDrawingInfo drawinfo = new ClientDrawingInfo(); drawinfo = (ClientDrawingInfo)Packet.Deserialize(readBuffer); DisplayText(drawinfo.clientNum + "의 그림 도착"); fileStrm = new FileStream(Environment.CurrentDirectory + "\\Server\\bin\\Debug\\" + drawinfo.clientNum + "turn.jpg" , FileMode.Create, FileAccess.Write); break; } case (int)PacketType.그림: { ClientDrawing draw = new ClientDrawing(); draw = (ClientDrawing)Packet.Deserialize(readBuffer); drawReceived(draw.buffer, draw.count, draw.clientNum); break; } } }