async void ServerWindow_Closing(object sender, CancelEventArgs e) { if (clientList.Count > 0) { //Event leállítás e.Cancel = true; //Read in closed value CloseReadDelegate closeRead = new CloseReadDelegate(GetCloseStarted); bool closeStarted = (bool)this.Dispatcher.Invoke(DispatcherPriority.Normal, closeRead); //Ha még nincs elindítva, elindítom if (!closeStarted) { //Kilépés elindítva CloseWriteDelegate closeSet = new CloseWriteDelegate(SetCloseStarted); await this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, closeSet, true); //Kilépési adat Data msgToSend = new Data(); msgToSend.cmdCommand = Command.Close; msgToSend.strName = Data.SERVER_NAME; msgToSend.strRec = Data.PUBLIC_ID; msgToSend.strMessage = "<<<A szerver bezar>>>"; byte[] message = msgToSend.ToByte(); //Minden felhasználónak elküldöm foreach (ClientInfo clientInfo in clientList) { clientInfo.socket.BeginSend(message, 0, message.Length, SocketFlags.None, new AsyncCallback(OnSend), clientInfo.socket); } } else { new Thread(() => { MessageBox.Show("Várakozás a kliensek lecsatlakozására."); }).Start(); } } }
private void OnReceive(IAsyncResult ar) { try { Socket clientSocket = (Socket)ar.AsyncState; clientSocket.EndReceive(ar); //Transform the array of bytes received from the user into an //intelligent form of object Data Data msgReceived = new Data(byteData); //We will send this object in response the users request Data msgToSend = new Data(); byte[] message; //If the message is to login, logout, or simple text message //then when send to others the type of the message remains the same msgToSend.cmdCommand = msgReceived.cmdCommand; msgToSend.strName = msgReceived.strName; msgToSend.strRec = msgReceived.strRec; switch (msgReceived.cmdCommand) { case Command.Login: //Check if the user is authorized for access User connectedUser = new User(msgReceived.strName, msgReceived.strMessage); if (connectedUser.SearchInList(_users) >= 0) { //When a user logs in to the server then we add her to our //list of clients msgToSend.cmdCommand = Command.Accept; //message = msgToSend.ToByte(); //clientSocket.Send(message); ClientInfo clientInfo = new ClientInfo(); clientInfo.socket = clientSocket; clientInfo.strName = msgReceived.strName; clientList.Add(clientInfo); //Set the text of the message that we will broadcast to all users msgToSend.strMessage = "<<<" + msgReceived.strName + " csatlakozott a szobahoz>>>"; } else { //Decline the user msgToSend.cmdCommand = Command.Decline; msgToSend.strName = msgReceived.strName; msgToSend.strMessage = null; message = msgToSend.ToByte(); //Log it only on the server-side UpdateDelegate update = new UpdateDelegate(UpdateMessage); this.textBox1.Dispatcher.BeginInvoke(DispatcherPriority.Normal, update, "<<<" + msgReceived.strName + " megprobalt a szobahoz csatlakozni engedely nelkul>>>" + "\r\n"); //Send the message and close the connection clientSocket.Send(message, 0, message.Length, SocketFlags.None); clientSocket.Shutdown(SocketShutdown.Both); clientSocket.Close(); } break; case Command.Logout: //When a user wants to log out of the server then we search for her //in the list of clients and close the corresponding connection int nIndex = 0; foreach (ClientInfo client in clientList) { if (client.socket == clientSocket && client.strName.Equals(msgReceived.strName)) { clientList.RemoveAt(nIndex); break; } ++nIndex; } //Send ack data before closing - Only for the disconnectiong client //msgToSend.cmdCommand = Command.Logout; //msgToSend.strName = msgReceived.strName; msgToSend.strMessage = null; //A parancs és név marad, az üzenet törlődik. message = msgToSend.ToByte(); clientSocket.Send(message, 0, message.Length, SocketFlags.None); //Kapcsolat leállítása clientSocket.Shutdown(SocketShutdown.Both); clientSocket.Close(); msgToSend.strMessage = "<<<" + msgReceived.strName + " elhagyta a szobat>>>"; break; case Command.Message: //Set the text of the message that we will broadcast to all (if public) msgToSend.strMessage = msgReceived.strName + " -> " + (msgReceived.strRec.Equals(Data.PUBLIC_ID) ? "Mindenki" : msgReceived.strRec) + " : " + msgReceived.strMessage; break; case Command.Upload: //Get the correct IP IPEndPoint upEndPoint = clientSocket.RemoteEndPoint as IPEndPoint; //Create a delegate for upload handling string pathUp = Data.FILES_FOLDER + (msgReceived.strRec.Equals(Data.PUBLIC_ID) ? Data.PUBLIC_ID : (msgReceived.strName + "-" + msgReceived.strRec)); Directory.CreateDirectory(pathUp); UploadDelegate upload = new UploadDelegate(BeginUpload); this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, upload, upEndPoint.Address, pathUp + "\\" + msgReceived.strMessage, msgReceived.strName, msgReceived.strRec); msgToSend.strMessage = "<<<" + msgReceived.strName + " megkezdte a '" + System.IO.Path.GetFileName(msgReceived.strMessage) + "' nevu falj feltolteset>>>"; break; case Command.StartDownload: //Get the correct IP IPEndPoint downEndPoint = clientSocket.RemoteEndPoint as IPEndPoint; //Delete message msgToSend.strMessage = null; //Create a delegate for upload handling string pathDown = Data.FILES_FOLDER + (msgReceived.strName.Equals(Data.PUBLIC_ID) ? Data.PUBLIC_ID : (msgReceived.strName + "-" + msgReceived.strRec)); Directory.CreateDirectory(pathDown); DownloadDelegate download = new DownloadDelegate(BeginDownload); this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, download, downEndPoint.Address, pathDown + "\\" + msgReceived.strMessage); msgToSend.strMessage = "<<<" + msgReceived.strRec + " megkezdte a '" + System.IO.Path.GetFileName(msgReceived.strMessage) + "' nevu falj letolteset>>>"; break; case Command.DownloadAck: //Set the text of the message that we will broadcast to all (if public) msgToSend.strMessage = "<<<" + msgReceived.strRec + " befejezte a '" + System.IO.Path.GetFileName(msgReceived.strMessage) + "' nevu falj letolteset>>>"; break; case Command.DownloadList: //Delete message msgToSend.strMessage = null; //Create a delegate for upload handling string pathDirectory = Data.FILES_FOLDER + (msgReceived.strRec.Equals(Data.PUBLIC_ID) ? Data.PUBLIC_ID : (msgReceived.strRec + "-" + msgReceived.strName)); Directory.CreateDirectory(pathDirectory); //Collect all filenames bool notFirstDownFiles = false; foreach (string file in Directory.GetFiles(pathDirectory)) { if (notFirstDownFiles) { msgToSend.strMessage += "*"; } else { notFirstDownFiles = true; } msgToSend.strMessage += System.IO.Path.GetFileName(file); } message = msgToSend.ToByte(); //Send the filenames clientSocket.BeginSend(message, 0, message.Length, SocketFlags.None, new AsyncCallback(OnSend), clientSocket); break; case Command.List: //Send the names of all users in the chat room to the new user msgToSend.cmdCommand = Command.List; msgToSend.strName = msgReceived.strName; msgToSend.strMessage = null; //Collect the names of the user in the chat bool notFirstList = false; foreach (ClientInfo client in clientList) { //To keep things simple we use asterisk as the marker to separate the user names if (notFirstList) { msgToSend.strMessage += "*"; } else { notFirstList = true; } msgToSend.strMessage += client.strName; } message = msgToSend.ToByte(); //Send the name of the users in the chat room clientSocket.BeginSend(message, 0, message.Length, SocketFlags.None, new AsyncCallback(OnSend), clientSocket); break; } if (!(msgToSend.cmdCommand == Command.List || msgToSend.cmdCommand == Command.DownloadList || msgToSend.cmdCommand == Command.Decline)) //List and decline messages are not broadcasted { message = msgToSend.ToByte(); foreach (ClientInfo clientInfo in clientList) { if (clientInfo.socket != clientSocket || msgToSend.cmdCommand != Command.Login) { //A publikus az broadcast, amúgy csak a 2 partnernek megy. -> Figyelni kell, hogy PUBLIC legyen alapból a cél, és feladó is legyen mindig. if (msgToSend.strRec.Equals(Data.PUBLIC_ID) || clientInfo.strName.Equals(msgReceived.strRec) || clientInfo.strName.Equals(msgReceived.strName)) { //Send the message to all users clientInfo.socket.BeginSend(message, 0, message.Length, SocketFlags.None, new AsyncCallback(OnSend), clientInfo.socket); //clientInfo.socket.Send(message, 0, message.Length, SocketFlags.None); } } } UpdateDelegate update = new UpdateDelegate(UpdateMessage); this.textBox1.Dispatcher.BeginInvoke(DispatcherPriority.Normal, update, msgToSend.strMessage + "\r\n"); } //If the user is logging out or declined, then we need not listen from her if (!(msgReceived.cmdCommand == Command.Logout || msgToSend.cmdCommand == Command.Decline)) { //Start listening to the message send by the user clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(OnReceive), clientSocket); } //Check if it's the last logout if (msgReceived.cmdCommand == Command.Logout && clientList.Count <= 0) { //Check if we started a close CloseReadDelegate closeRead = new CloseReadDelegate(GetCloseStarted); bool closeStarted = (bool)this.Dispatcher.Invoke(DispatcherPriority.Normal, closeRead); //Finish the close if (closeStarted) { CloseDelegate closeRun = new CloseDelegate(CloseRun); this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, closeRun); } } } catch (Exception ex) { new Thread(() => { MessageBox.Show(ex.Message, "Server Receive"); }).Start(); } }