Hi guys,
I'm new to c++ and indeed socket programming but as I've said in a few other threads I've joined in on, I've been programming for a while.
I'm a little stuck on how I can achieve multiple connections to a single port in c++. I understand that each connection needs to be stored in an array, but how to identify the connection when it talks to the server is another thing..
Should each connection be given a unique id (hashed) and it gets passed through everytime it talks to the server? This seems a little unneeded as 1. it could be comprimised and hence a security issue, 2. each connection sits on its own unique (??) socket. Does the TCP/IP protocol remember the sockets for each connection or do I do that?
Soooo many questions, I've been plugging away at some code I found for tcp server/client trying to get it to do multiple clients and Its just creating more and more questions.. Sorry if these are very basic questions, but I would appreciate any guidance anybody is willing to answer.. for those looking for some starter code here is what I have.
from http://sage.mc.yu.edu/kbeen/teaching...s/sockets.html
Code:
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <iostream>
#define MAX_MSG 100
#define LINE_ARRAY_SIZE (MAX_MSG+1)
using namespace std;
int main()
{
int listenSocket, connectSocket[50], i, connection;
unsigned short int listenPort;
socklen_t clientAddressLength;
struct sockaddr_in clientAddress, serverAddress;
char line[LINE_ARRAY_SIZE];
cout << "Enter port number to listen on (between 1500 and 65000): ";
cin >> listenPort;
// 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.
connection = 0;
clientAddressLength = sizeof(clientAddress);
connectSocket[connection] = accept(listenSocket,
(struct sockaddr *) &clientAddress,
&clientAddressLength);
cout << "Connect socket? " << connectSocket;
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[connection], line, MAX_MSG, 0) > 0) {
cout << " -- " << line << "\n";
// Convert line to upper case.
for (i = 0; line[i] != '\0'; i++) {
if( (i % 2) == 0)
line[i] = toupper(line[i]);
}
// Send converted line back to client.
if (send(connectSocket[connection], line, strlen(line) + 1, 0) < 0)
cerr << "Error: cannot send modified data";
memset(line, 0x0, LINE_ARRAY_SIZE); // set line to all zeroes
}
}
}
As you can see, I've started by creating an int array with max connections = 50.