Improve server to deal with multiple clients - c++

I'm trying to create a server that talks with 2 clients, 1 in each time. After the talking with one client, the server sends a message to both clients.
I found a basic code of a server, and I tried to upgrade it to accept multiple number of connections, and I saw 2 ways of it : threads, or doing array of sockets, but I couldn't understand it.
Can someone explain me how to use threads and give examples please?
This is the code :
int main()
{
WSADATA WsaDat;
if (WSAStartup(MAKEWORD(2, 2), &WsaDat) != 0)
{
std::cout << "WSA Initialization failed!\r\n";
WSACleanup();
system("PAUSE");
return 0;
}
SOCKET Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (Socket == INVALID_SOCKET)
{
std::cout << "Socket creation failed.\r\n";
WSACleanup();
system("PAUSE");
return 0;
}
SOCKADDR_IN serverInf;
serverInf.sin_family = AF_INET;
serverInf.sin_addr.s_addr = INADDR_ANY;
serverInf.sin_port = htons(8888);
if (bind(Socket, (SOCKADDR*)(&serverInf), sizeof(serverInf)) == SOCKET_ERROR)
{
std::cout << "Unable to bind socket!\r\n";
WSACleanup();
system("PAUSE");
return 0;
}
listen(Socket, 1);
SOCKET TempSock = SOCKET_ERROR;
while (TempSock == SOCKET_ERROR)
{
std::cout << "Waiting for incoming connections...\r\n";
TempSock = accept(Socket, NULL, NULL);
}
// If iMode!=0, non-blocking mode is enabled.
u_long iMode = 1;
ioctlsocket(Socket, FIONBIO, &iMode);
Socket = TempSock;
std::cout << "Client connected!\r\n\r\n";
// Main loop
for (;;)
{
char *szMessage = "Welcome to the server!\r\n";
send(Socket, szMessage, strlen(szMessage), 0);
int nError = WSAGetLastError();
if (nError != WSAEWOULDBLOCK&&nError != 0)
{
std::cout << "Winsock error code: " << nError << "\r\n";
std::cout << "Client disconnected!\r\n";
// Shutdown our socket
shutdown(Socket, SD_SEND);
// Close our socket entirely
closesocket(Socket);
break;
}
Sleep(1000);
}
WSACleanup();
system("PAUSE");
return 0;
}

To do so you need one server socket and a clientsocket array like this:
SERVER:
ACCEPT:
int clientsock[2];
minsocks = 0;
numsocks = 2;
while(minsock < numsocks)
{
clientsock[minsock] = accept(serversock,
(struct sockaddr *) &clientaddr,
(socklen_t *)&clientaddrlen);
minsock++;
}
RECIEVE:
char message[6];
int data;
int limit = 6;
for(int i = 0; i < NUMSOCK; i++)
{
int in = recv(clientsock[i], &message[index], limit, 0);
if(in > 0)
{
index += in;
limit -= in;
}
else if ( in == 0 )
printf("Connection closed\n");
else
printf("recv failed: %d\n", WSAGetLastError());
}
This should be a good beginning for you to start with.
Threads - C version
pthread_t sniffer_thread;
if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0)
{
perror("could not create thread");
return 1;
}
//Now join the thread , so that we dont terminate before the thread
//pthread_join( sniffer_thread , NULL);
puts("Handler assigned");
}
/*
* This will handle connection for each client
* */
void *connection_handler(void *socket_desc)
{
//Get the socket descriptor
int sock = *(int*)socket_desc;
int read_size;
char *message , client_message[2000];
while(in != 0)
{
int in = recv(socket_desc, &client_message[index], limit, 0);
if(in > 0)
{
index += in;
limit -= in;
}
else
printf("recv failed: %d\n", WSAGetLastError());
}
//Free the socket pointer
free(socket_desc);
return 0;
}

Related

I want to implement a simple multicast chat program. send thread and a receive thread are created and executed, but reception is not activated

I want to create two projects with this code so that they can chat with each other, but no matter how much I send, the data does not reach the other client.
I've been thinking and trying for hours on this problem, but it doesn't work. Various multicast chat programs on the web are written in languages other than C++, some use threads and some do not. To the best of my knowledge right now, I can't understand the codes on the web.
For fear of lengthy code, the basic header file and error output function have been omitted.
// header file and function declaration
#define MAXBUF 80
SOCKADDR_IN maddr;
int main(int argc, char* argv[]) {
int port;
cout << "input port number" << endl;
cin >> port;
cout << "use port : " << port << endl;
WSADATA wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa))
{
err_display("WSAStartup");
return -1;
}
//create send socket
SOCKET r_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (r_sock == INVALID_SOCKET)
{
err_display(" recv socket");
return -1;
}
//create recv socket
SOCKET s_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s_sock == INVALID_SOCKET)
{
err_display(" send socket");
return -1;
}
// bind
maddr.sin_family = AF_INET;
maddr.sin_port = htons(port);
maddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(r_sock, (SOCKADDR*)&maddr, sizeof(maddr))) {
err_display("bind");
return -1;
}
// Join the Multicast address
const char* mip = "236.0.0.1";
IP_MREQ mreq;
mreq.imr_interface.s_addr = htonl(INADDR_ANY); // s_addr = 주소
// Setting Multicast address
if (!(inet_pton(AF_INET, mip, &mreq.imr_multiaddr))) {
err_display("inet_pton");
return -1;
}
// JOIN
if (setsockopt(r_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mreq, sizeof(mreq))) {
err_display("setsockopt");
return -1;
}
while (true) {
HANDLE h1 = (HANDLE)_beginthreadex(NULL, 0, &sendf, (LPVOID)s_sock, 0, NULL);
HANDLE h2 = (HANDLE)_beginthreadex(NULL, 0, &recvf, (LPVOID)r_sock, 0, NULL);
}
closesocket(r_sock);
closesocket(s_sock);
WSACleanup();
return 0;
}
unsigned __stdcall sendf(LPVOID arg) // send thread function
{
SOCKET s_sock = (SOCKET)arg;
char mesbuf[MAXBUF];
int sendlen;
while (1)
{
// send
char mesbuf[MAXBUF];
if (fgets(mesbuf, MAXBUF - 1, stdin) == NULL)
break;
cout << "send Thread" << endl;
sendlen = strlen(mesbuf);
sendto(s_sock, mesbuf, sendlen, 0, (SOCKADDR*)&maddr, sizeof(maddr));
}
return 0;
}
unsigned __stdcall recvf(LPVOID arg) // recv thread function
{
SOCKADDR_IN paddr; // peer address
int namelen = sizeof(paddr);
SOCKET r_sock = (SOCKET)arg;
char mesbuf[MAXBUF];
int recvlen;
while (1)
{
char mesbuf[MAXBUF];
//recive
recvlen = recvfrom(r_sock, mesbuf, MAXBUF - 1, 0, (SOCKADDR*)&paddr, &namelen);
cout << "recv Thread" << endl;
if (recvlen == SOCKET_ERROR) {
err_display("recv error");
closesocket(r_sock);
break;
}
if (recvlen == 0)
{
cout << "normal close connection case" << endl;
closesocket(r_sock);
break;
}
mesbuf[recvlen] = '\0'; // string conversion
cout << "from : " << mesbuf << endl;
}
return 0;
}

C++ Socket API "Heartbeat"

I'm trying to make a simple heartbeat check from client to server and vice-versa, if connection on either is broken off unexpectedly it prints a message and calls closesocket.
I spent 8 hours on this and it still isn't acceptable to my mentor. Right now I got something that works, but if breakpoint is placed before while loop and connected client is forcefully closed, trying to go past breakpoint causes crash when it should break the loop and write out error.
Server side code:
int main(int argc, char *argv[])
{
SOCKET s, sa;
WSAData oWSAData;
WORD wVersion = 0x0001;
WSAStartup(wVersion, &oWSAData);
s = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in srv_address;
memset(&srv_address, 0, sizeof(srv_address));
srv_address.sin_family = AF_INET;
srv_address.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
srv_address.sin_port = htons(1099);
bind(s, (sockaddr*) &srv_address, sizeof(srv_address));
int l = listen(s, 10);
if (l < 0)
printf("Listen error\n");
else
{
printf("Listen OK. Listening on port %u\n",
htons(srv_address.sin_port));
sa = accept(s, NULL, NULL);
while (true)
{
char buffer[1000];
int nRecvLen = recv(sa, buffer, 999, 0);
buffer[nRecvLen] = '\0';
int r = recv(sa, NULL, 0, 0);
if (r == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET)
{
printf("Konekcija je naglo prekinuta!\n");
break;
}
else
{
if (nRecvLen > 0)
{
for (int i = 0; i < nRecvLen; i++)
{
cout << buffer[i];
}
}
}
}
closesocket(sa);
closesocket(s);
}
WSACleanup();
return 0;
}
and client side:
int main()
{
SOCKET s;
WSAData oWSAData;
WORD wVersion = 0x0001;
WSAStartup(wVersion, &oWSAData);
s = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in srv_address;
memset(&srv_address, 0, sizeof(srv_address));
srv_address.sin_family = AF_INET;
srv_address.sin_addr.S_un.S_un_b.s_b1 = xxx;
srv_address.sin_addr.S_un.S_un_b.s_b2 = xxx;
srv_address.sin_addr.S_un.S_un_b.s_b3 = x;
srv_address.sin_addr.S_un.S_un_b.s_b4 = xxx;
srv_address.sin_port = htons(1099);
int c = connect(s, (sockaddr*) &srv_address, sizeof(srv_address));
if (c < 0)
{
printf("Connection error\n");
cout << (WSAGetLastError());
}
else
{
string l = "Heartbeat\n";
int p = l.size();
char buff[1000];
strcpy_s(buff, l.c_str());
printf("Connected\n");
while (true)
{
if (send(s, buff, p, 0) > 0)
{
Sleep(1000);
}
else
{
printf("Konekcija je naglo prekinuta\n");
shutdown(s, SD_BOTH);
closesocket(s);
break;
}
}
WSACleanup();
return 0;
}
}

C++ low throughput winsock TCP test application

I'm trying to build a fast server & client which work in localhost. The idea is to send data blobs from another program, and be quick about it. only one client connects to the server at a time.
I first tried implementing this using boost::asio library. everything worked fine, except that the throughput was abysmally slow, 415megabytes/s.
Then I proceeded to create a testcase with winsock, it too had very similar throughput, 434megabytes/s. abysmally slow.
I was expecting more of at range of 40Gigabytes or at least several gigabytes per second.
Id appreaciate any suggestions, as I am way out of my element, with networks programming.
My current client function:
bool sendDataWin(size_t size, const size_t blocksize, size_t port)
{
int result;
struct addrinfo *addressinfo = nullptr, hints;
auto sport = std::to_string(port);
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the local address and port to be used by the server
result = getaddrinfo("localhost", sport.c_str(), &hints, &addressinfo);
if (result != 0) {
printf("Error at client socket(): %ld\n", WSAGetLastError());
return false;
}
SOCKET connection = socket(
addressinfo->ai_family,
addressinfo->ai_socktype,
addressinfo->ai_protocol);
if (connection == INVALID_SOCKET) {
printf("Error at client socket(): %ld\n", WSAGetLastError());
freeaddrinfo(addressinfo);
return false;
}
// Try to put loopback fast path on.
bool value;
DWORD dwBytesRet;
int status =
WSAIoctl(
connection,
SIO_LOOPBACK_FAST_PATH,
&value,
sizeof(bool),
NULL,
0,
&dwBytesRet,
0,
0);
if (status == SOCKET_ERROR) {
DWORD LastError = ::GetLastError();
if (LastError == WSAEOPNOTSUPP) {
printf("client call is not supported :: SIO_LOOPBACK_FAST_PATH\n");
}
}
// Connect to server.
result = connect(connection, addressinfo->ai_addr, (int)addressinfo->ai_addrlen);
if (result == SOCKET_ERROR) {
printf("Error at client socket(): %ld\n", WSAGetLastError());
closesocket(connection);
return false;
}
freeaddrinfo(addressinfo);
std::vector<uint8_t> buffer;
buffer.resize(blocksize);
size_t total = 0;
do {
size_t sendSize = blocksize;
size_t next = total + sendSize;
if (next > size)
{
sendSize -= next - size;
}
// Echo the buffer back to the sender
result = send(connection, (const char*)buffer.data(), (int)sendSize, 0);
if (result == SOCKET_ERROR) {
printf("client send failed: %d\n", WSAGetLastError());
closesocket(connection);
return false;
}
total += sendSize;
} while (total < size);
result = shutdown(connection, SD_SEND);
if (result == SOCKET_ERROR) {
printf("client shutdown failed: %d\n", WSAGetLastError());
closesocket(connection);
return false;
}
// cleanup
closesocket(connection);
return true;
}
server function:
bool serverReceiveDataWin(size_t size, const size_t blocksize, size_t port)
{
int result;
struct addrinfo *addressinfo = nullptr, *ptr = nullptr, hints;
auto sport = std::to_string(port);
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the local address and port to be used by the server
result = getaddrinfo(nullptr, sport.c_str(), &hints, &addressinfo);
if (result != 0) {
printf("Error at server socket(): %ld\n", WSAGetLastError());
return false;
}
SOCKET ListenSocket = socket(addressinfo->ai_family, addressinfo->ai_socktype, addressinfo->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printf("Error at server socket(): %ld\n", WSAGetLastError());
freeaddrinfo(addressinfo);
return false;
}
// Try to put loopback fast path on.
bool value;
DWORD dwBytesRet;
int status =
WSAIoctl(
ListenSocket,
SIO_LOOPBACK_FAST_PATH,
&value,
sizeof(bool),
NULL,
0,
&dwBytesRet,
0,
0);
if (status == SOCKET_ERROR) {
DWORD LastError = ::GetLastError();
if (LastError == WSAEOPNOTSUPP) {
printf("server call is not supported :: SIO_LOOPBACK_FAST_PATH\n");
}
}
// Setup the TCP listening socket
result = bind(ListenSocket, addressinfo->ai_addr, (int)addressinfo->ai_addrlen);
if (result == SOCKET_ERROR) {
printf("server bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(addressinfo);
closesocket(ListenSocket);
return false;
}
if (listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR) {
printf("Listen failed with error: %ld\n", WSAGetLastError());
closesocket(ListenSocket);
return false;
}
// Accept a client socket
SOCKET ClientSocket = accept(ListenSocket, nullptr, nullptr);
if (ClientSocket == INVALID_SOCKET) {
printf("server accept failed: %d\n", WSAGetLastError());
closesocket(ListenSocket);
return false;
}
std::vector<uint8_t> buffer;
buffer.resize(blocksize);
size_t total = 0;
// Receive until the peer shuts down the connection
do {
size_t currentSize = blocksize;
size_t next = total + currentSize;
if (next > size)
{
currentSize -= next - size;
}
result = recv(ClientSocket, (char*)buffer.data(), (int)currentSize, 0);
if (result > 0)
{
total += result;
}
else if (result == 0)
{
printf("server Connection closing...\n");
return false;
}
else {
printf("server recv failed: %d\n", WSAGetLastError());
closesocket(ClientSocket);
return false;
}
} while (total < size);
result = shutdown(ClientSocket, SD_SEND);
if (result == SOCKET_ERROR) {
printf("server shutdown failed: %d\n", WSAGetLastError());
closesocket(ClientSocket);
return false;
}
// cleanup
closesocket(ClientSocket);
return true;
}
and the test program itself is:
int main()
{
int width = 1920;
int height = 1080;
const size_t totalBpp = 3;
const size_t totalSize = width * height * totalBpp;
size_t port = 27140;
size_t times = 1000;
size_t expectedData = totalSize * times;
// Initialize Winsock
int iResult;
WSADATA wsaData;
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
std::cout << "WSAStartup failed: " << iResult << std::endl;
return EXIT_FAILURE;
}
std::atomic_bool serverOk{ false };
std::atomic_bool clientOk{ false };
auto start = std::chrono::high_resolution_clock::now();
std::thread server = std::thread([&] {
serverOk = serverReceiveDataWin(expectedData, totalSize, port);
});
std::thread client = std::thread([&] {
clientOk = sendDataWin(expectedData, totalSize, port);
});
client.join();
server.join();
auto end = std::chrono::high_resolution_clock::now();
WSACleanup();
if (!(clientOk && serverOk))
{
if (!serverOk) std::cout << "Server was not OK." << std::endl;
if (!clientOk) std::cout << "Client was not OK." << std::endl;
return EXIT_FAILURE;
}
std::chrono::duration<double> diff = end - start;
double frameTime = diff.count() / times;
double fps = 1.0 / frameTime;
std::cout << "Sent: " << width << "x" << height << "_" << totalBpp << "(" << totalSize << "). times: " << times << std::endl;
std::cout << "frameTime: " << frameTime << "s." << std::endl;
std::cout << "fps: " << fps << "." << std::endl;
std::cout << "transfer rate : " << ((expectedData / diff.count()) / 1048576) << " mebibytes/s." << std::endl;
std::cout << "transfer rate : " << ((expectedData / diff.count()) / 1000000) << " megabytes/s." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds{ 60 });
return EXIT_SUCCESS;
}
on my machine I get these results:
Sent: 1920x1080_3(6220800).times : 1000
frameTime : 0.0138217s.
fps : 72.35.
transfer rate : 429.225 mebibytes / s.
transfer rate : 450.075 megabytes / s.
It seems that the issue was somewhat my firewall/anti-virus, I first unloaded F-secure, the speeds increased to 500megabytes/s.. after uninstall & reboot, the speeds increased to 4000megabytes/s.
A couple points.
the IOCTL is not called correctly.
bool value;
DWORD dwBytesRet;
int status =
WSAIoctl(
ListenSocket,
SIO_LOOPBACK_FAST_PATH,
&value,
sizeof(bool),
NULL,
0,
&dwBytesRet,
0,
0);
This should pass in a DWORD (32 bit integer) set to 1. The above code passes a C++ bool (probably only 1 byte) that was never initialized to anything.
Since this is only a single socket, this is going to be CPU limited, since it's effectively going to just be going from user/kernel and memcopying on a single thread. It's not likely that this will hit 40 Gbps over a single connection. Particularly since this is only sending 6GB worth of data.
You should turn off Nagle's Algorithm when sending large amounts of data like this. Set TCP_NODELAY on the sending socket.

error in send data to server

Why when run the program and send data to server return this errorrecv failed: Transport endpoint is not connected or don't show server accepted just show the message of send data function in client
server.cpp:
int main() {
char packet[30];
char buffer[20] = "I got your message";
int conn_sock, comm_sock, n, m;
struct sockaddr_in server_addr, client_addr;
if ((conn_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Couldn't create socket");
exit(1);
}
cout << "Already create socket!!!\n" << endl;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(0);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
memset(&server_addr, 0, sizeof(server_addr));
if (bind(conn_sock, (struct sockaddr *) &server_addr, sizeof(server_addr))
== -1) {
perror("couldn't bind");
exit(1);
}
if (listen(conn_sock, 10) == -1) {
perror("couldn't listen");
exit(1);
}
cout << "Listening For Connection...\r" << endl;
socklen_t len = sizeof(server_addr);
if (getsockname(conn_sock, (struct sockaddr *) &server_addr, &len) == -1)
perror("getsockname");
else
printf("port number %d\n", ntohs(server_addr.sin_port));
while (1) {
memset(&client_addr, 0, sizeof(client_addr));
if ((comm_sock = accept(conn_sock, (struct sockaddr *) &client_addr,
(socklen_t *) &client_addr)) == -1) {
perror("couldn't accept\n");
continue;
}
cout << "accepted" << endl;
bzero(packet, 10);
m = recv(conn_sock, packet, 10, 0);
if (m < 0) {
perror("recv failed");
exit(1);
}
cout<<"recieved"<<endl;
/* Write a response to the client */
n = send(conn_sock, buffer, sizeof(buffer), 0);
if (n < 0) {
perror("ERROR send to client");
exit(1);
}
close(n);
close(m);
close(comm_sock);
}
close(conn_sock);
return 0;
}
cilent.cpp:
#define MYPORT 51833
namespace personalization {
bool client::conn() {
//create socket if it is not already created
if (sock == -1) {
//Create socket
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
perror("Could not create socket");
}
cout << "Socket created" << endl;
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(MYPORT);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(sock , (struct sockaddr *)&server_addr , sizeof(server_addr)) < 0)
{
perror("connect failed. Error");
return false;
}
cout<<"Connected\n";
return true;
close(sock);
}
bool client::send_data() {
//Send some data
if( send(sock , packet , sizeof( packet ) , 0) < 0)
{
perror("Send failed");
return false;
}
cout<<"Data send\n";
return true;
close(sock);
}
bool client::rec_data() {
char buffer[20];
string reply;
//Receive a echo from the server
if (recv(sock, buffer, sizeof(buffer), 0) < 0) {
perror("receive failed");
return false;
}
reply = buffer;
return true;
close(sock);
}
client::client() {
// TODO Auto-generated constructor stub
sock=-1;
}
output is:
server:Already create socket!!!
Listening For Connection...
port number 51833
client: Socket created
Connected
Data send
receive failed: Connection reset by peer
or:
server:Already create socket!!!
Listening For Connection...
port number 51833
client:Socket created
Connected
Data send
srver:accepted
recv failed: Transport endpoint is not connected
In the server's recv and send calls, you need to pass the socket returned from accept.
So instead of
m = recv(conn_sock, packet, 10, 0);
do
m = recv(comm_sock, packet, 10, 0);
Same goes for the send call.
Also, don't call close on n and m, that is to say remove these two lines of code:
close(n);
close(m);
EDIT: Sorry, while I'm at it, this is probably not what you intended in the client's send_data and rec_data:
return true;
close(sock);

Server does not respond to new clients using select(), cpp

I followed this nice tutorial to create a simple non-blocking server using select() function. Here's what I have:
void setNonBlocking(int socketFD) {
int x;
x = fcntl(socketFD,F_GETFL,0);
fcntl(socketFD,F_SETFL,x | O_NONBLOCK);
return;
}
int initialize(char * port) {
int yes = 1;
listener = socket(PF_INET,SOCK_STREAM, 0);
if (listener < 0) {
perror("listener");
exit(EXIT_FAILURE);
}
if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
setNonBlocking(listener);
struct sockaddr_in server_address;
memset((char *) &server_address, 0, sizeof(server_address));
server_address.sin_family = AF_INET;
// server_address.sin_addr.s_addr = htonl(INADDR_ANY);
inet_aton("132.65.151.39",&(server_address.sin_addr));
server_address.sin_port = htons(atoi(port));
if (bind(listener, (struct sockaddr *) &server_address,
sizeof(server_address)) < 0 ) {
perror("bind");
close(listener);
exit(EXIT_FAILURE);
}
listen(listener,BACKLOG);
maxSocket = listener;
memset((char *) &clientQueue, 0, sizeof(clientQueue));
return 0;
}
void readSockets() {
int i;
cout << "in readSockets()" << endl;
if (FD_ISSET(listener,&sockets))
createConnection();
for (i = 0; i < 5; i++) {
if (FD_ISSET(clientQueue[i],&sockets))
readData(i);
} /* for (all entries in queue) */
}
int main(int argc, char* argv[]) {
if (argc != 2) {
fprintf(stderr,"usage: server port\n");
exit(EXIT_FAILURE);
}
if (initialize(argv[1]) != 0) {
exit(EXIT_FAILURE);
}
struct timeval timeout;
int value;
printf("server: waiting for connections...\n");
while(1) { // main accept() loop
build_select_list();
timeout.tv_sec = 1;
timeout.tv_usec = 0;
value = select(maxSocket, &sockets, (fd_set *) 0,(fd_set *) 0, &timeout);
if (value == -1) {
perror("select");
exit(EXIT_FAILURE);
}
if (value == 0) {
printf("%d",value);
fflush(stdout);
} else{
cout << "Value is " << value << endl;
readSockets();
}
}
return EXIT_SUCCESS;
}
My problem is simple - select always returns 0, meaning it does not get or does not respond to a new connection. I checked my client a day ago with a blocking more simple server and it did work, so I don't think its the porblem.
You'll notice that I tried both IP addresses:
server_address.sin_family = AF_INET;
// server_address.sin_addr.s_addr = htonl(INADDR_ANY);
Can anyone please help me? I feel lost :)
Please refer to man select, first parameter should be number of highest descriptor + 1, so in your case:
value = select(maxSocket + 1, &sockets, (fd_set *) 0,(fd_set *) 0, &timeout);