void CServerConsole::OnSocketEvent(wxSocketEvent& event){ wxSocketBase *sock = event.GetSocket(); switch(event.GetSocketEvent()){ case wxSOCKET_LOST:{ Log(wxString::FromAscii("Client disconnected")); sock->Destroy(); break; } case wxSOCKET_INPUT:{ // Disable input events, not to trigger wxSocketEvent again sock->SetNotify(wxSOCKET_LOST_FLAG); ClientHandshake handshake; sock->ReadMsg(&handshake, sizeof(handshake)); if (sock->Error()){ Log(wxString::FromAscii("Error receiving client message")); sock->Close(); return; } Log(wxString::FromAscii("Got a handshake")); int iClientID = handshake.id; if ((iClientID == -1) || ((iClientID > 0) && !IsClientIDValid(iClientID))){ iClientID = CreateNewClient(iClientID); } ServerReply reply; reply.id = iClientID; reply.status = 1; if (!IsClientIDValid(iClientID)) reply.status = -1; sock->WriteMsg(&reply, sizeof(reply)); if (sock->Error()){ Log(wxString::FromAscii("Error sending a reply")); return; } Log(wxString::FromAscii("Sent a reply")); if (!IsClientIDValid(iClientID)) return; ReceiveClientCommand(iClientID, sock); // Enable input events again. sock->SetNotify(wxSOCKET_LOST_FLAG | wxSOCKET_INPUT_FLAG); break; } default: wxASSERT(0); } }
/************************************************************** * * Entry: * * socket - the socket file descriptor * * cHostName - the actual client host name * * * * Exit: * * N/a * * * * Purpose: * * This code gets run in the forked process to handle the actual * * server processing of the client request. * * * ***************************************************************/ void handleRequest(int commandSocket, char *cHostName) { int dataPort = -1; char clientCommand[BUFFERLENGTH]; bzero(clientCommand, BUFFERLENGTH); char transferFileName[BUFFERLENGTH]; bzero(transferFileName, BUFFERLENGTH); char clientHostName[BUFFERLENGTH]; // Note: this variable is the ftserver hostname bzero(clientHostName, BUFFERLENGTH); ReceiveClientCommand(commandSocket, clientCommand, transferFileName, &dataPort, clientHostName); OutputServerReqMsg(clientCommand, transferFileName, dataPort); close(commandSocket); // Get IP address from ftclient host name char IP[100]; HostnameToIp(cHostName, IP); int dataSocket; struct sockaddr_in remote_addr; // Get the Socket file descriptor if ((dataSocket = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Error: Failed to obtain socket descriptor.\n"); exit(2); } // Fill the socket address struct remote_addr.sin_family = AF_INET; remote_addr.sin_port = htons(dataPort); inet_pton(AF_INET, IP, &remote_addr.sin_addr); bzero(&(remote_addr.sin_zero), 8); // Try to connect the client data port if (connect(dataSocket, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr)) == -1) { printf("Error: could not contact client on port %d\n", dataPort); exit(2); } if (strcmp(clientCommand, "-l") == 0) { printf("Sending directory contents to %s:%d.\n", clientHostName, dataPort); SendFileListToServer(dataSocket); } else if (strcmp(clientCommand, "-g") == 0) { // Reference: http://stackoverflow.com/questions/230062/whats-the-best-way-to-check-if-a-file-exists-in-c-cross-platform if(access(transferFileName, F_OK) != -1) { // File exists SendFtClientFileStatus(dataSocket, "s"); printf("Sending \"%s\" to %s:%d\n", transferFileName, cHostName, dataPort); SendFileToServer(dataSocket, transferFileName); } else { // File doesnt exist printf("File not found. Sending error message to %s:%d\n", cHostName, dataPort); SendFtClientFileStatus(dataSocket, "e"); } } close(dataSocket); exit(0); // Exiting the child process. }