/*************************************************************************** * Copyright (C) 2007 by mati * * infecto@lcm.pl * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #define MAX_MSG 100 #define LINE_ARRAY_SIZE (MAX_MSG+1) using namespace std; int main(int argc, char** argv) { int listenSocket, connectSocket, i; unsigned short int listenPort; socklen_t clientAddressLength; struct sockaddr_in clientAddress, serverAddress; char line[LINE_ARRAY_SIZE]; listenPort = atoi(argv[1]); // Create socket for listening for client connection requests. listenSocket = socket(AF_INET, SOCK_STREAM, 0); if (listenSocket < 0) { cerr << "cannot create listen socket"; exit(1); } // Bind listen socket to listen port. First set various fields in // the serverAddress structure, then call bind(). // htonl() and htons() convert long integers and short integers // (respectively) from host byte order (on x86 this is Least // Significant Byte first) to network byte order (Most Significant // Byte first). serverAddress.sin_family = AF_INET; serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); serverAddress.sin_port = htons(listenPort); if (bind(listenSocket, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0) { cerr << "cannot bind socket"; exit(1); } // Wait for connections from clients. // This is a non-blocking call; i.e., it registers this program with // the system as expecting connections on this socket, and then // this thread of execution continues on. listen(listenSocket, 5); while (1) { cout << "Waiting for TCP connection on port " << listenPort << " ...\n"; // Accept a connection with a client that is requesting one. The // accept() call is a blocking call; i.e., this thread of // execution stops until a connection comes in. // connectSocket is a new socket that the system provides, // separate from listenSocket. We *could* accept more // connections on listenSocket, before connectSocket is closed, // but this program doesn't do that. clientAddressLength = sizeof(clientAddress); connectSocket = accept(listenSocket, (struct sockaddr *) &clientAddress, &clientAddressLength); if (connectSocket < 0) { cerr << "cannot accept connection "; exit(1); } // Show the IP address of the client. // inet_ntoa() converts an IP address from binary form to the // standard "numbers and dots" notation. cout << " connected to " << inet_ntoa(clientAddress.sin_addr); // Show the client's port number. // ntohs() converts a short int from network byte order (which is // Most Significant Byte first) to host byte order (which on x86, // for example, is Least Significant Byte first). cout << ":" << ntohs(clientAddress.sin_port) << "\n"; // Read lines from socket, using recv(), storing them in the line // array. If no messages are currently available, recv() blocks // until one arrives. // First set line to all zeroes, so we'll know where the end of // the string is. memset(line, 0x0, LINE_ARRAY_SIZE); while (recv(connectSocket, line, MAX_MSG, 0) > 0) { cout << " -- " << line << "\n"; // Convert line to upper case. for (i = 0; line[i] != '\0'; i++) line[i] = toupper(line[i]); // Send converted line back to client. if (send(connectSocket, line, strlen(line) + 1, 0) < 0) cerr << "Error: cannot send modified data"; memset(line, 0x0, LINE_ARRAY_SIZE); // set line to all zeroes } } }