select function windows vs linux - c++

i've the following code which runs just fine under windows env while in linux using the same code it doesn't (besides few changes of libs) .the select function does not respond to new connections.
The relevant code is as follows:
struct SocketState
{
int id; // Socket handle
int recv; // Receiving?
int send; // Sending?
int sendSubType; // Sending sub-type
char buffer[128];
int len;
int authenticate;
char userName[10];
};
struct SocketState sockets[MAX_SOCKETS]={0};
int socketsCount = 0;
int main()
{
int listenSocket = socket(PF_INET, SOCK_STREAM, 0);
if (-1 == listenSocket)
{
return 0 ;
}
struct sockaddr_in serverService;
serverService.sin_family = AF_INET;
serverService.sin_addr.s_addr = htonl(INADDR_ANY);
serverService.sin_port = htons(TIME_PORT);
if (-1 == bind(listenSocket, (struct sockaddr*)&serverService, sizeof(serverService)))
{
perror("Couldn't bind socket");
return -1;
}
if (-1 == listen(listenSocket, 10))
{
perror("Couldn't listen to port");
}
addSocket(listenSocket, LISTEN);
while (true)
{
fd_set waitRecv;
FD_ZERO(&waitRecv);
for (int i = 0; i < MAX_SOCKETS; i++)
{
if ((sockets[i].recv == LISTEN) || (sockets[i].recv == RECEIVE))
FD_SET(sockets[i].id, &waitRecv);
}
fd_set waitSend;
FD_ZERO(&waitSend);
for (int i = 0; i < MAX_SOCKETS; i++)
{
if (sockets[i].send == SEND)
FD_SET(sockets[i].id, &waitSend);
}
int nfd;
nfd = select(0, &waitRecv, &waitSend, NULL, NULL);
if (nfd == -1)
{
return 0 ;
}
}
}

You are passing 0 as the first argument to select. That is wrong. Probably in Windows this parameter is not used, but in linux it have to be set correctly.
It has to be set to the number of the higher fd plus 1.

Related

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;
}
}

What`s wrong with this socket select code?

#include <stdio.h>
#include <time.h>
#include <WinSock2.h>
#include <WS2tcpip.h>
#pragma comment(lib, "WS2_32.lib")
#define IP_ADDRESS "127.0.0.1"
#define PORT 20000
#define BUF_SIZE 64
#undef FD_SETSIZE
#define FD_SETSIZE 10000
void shuffle_buffer(char* buf, size_t size);
SOCKET create_socket();
void send_data(SOCKET sock);
int main()
{
WSADATA ws;
if (WSAStartup(MAKEWORD(2, 2), &ws) != 0)
{
printf("Init Windows Socket Failed::%d\n", GetLastError());
return -1;
}
const int CLIENT_SIZE = 1;
SOCKET socks[CLIENT_SIZE];
struct timeval tv = { 0, 10 };
fd_set fd_read, fd_write;
FD_ZERO(&fd_read);
FD_ZERO(&fd_write);
for (int i = 0; i < CLIENT_SIZE; i++) {
SOCKET sock = create_socket();
socks[i] = sock;
FD_SET(sock, &fd_write);
FD_SET(sock, &fd_read);
}
Sleep(1000);
int number_to_recv = CLIENT_SIZE;
while (number_to_recv > 0) {
int ret = select(CLIENT_SIZE, &fd_read, &fd_write, NULL, &tv);
for (int i = 0; i < CLIENT_SIZE; i++) {
if (FD_ISSET(socks[i], &fd_read)) {
char buf[BUF_SIZE];
int n = recv(socks[i], buf, BUF_SIZE, 0);
buf[n] = 0;
printf("%s\n", buf);
number_to_recv--;
}
if (FD_ISSET(socks[i], &fd_write)) {
send_data(socks[i]);
FD_CLR(socks[i], &fd_write);
//Sleep(1);
}
}
//printf("ret and number : %d, %d\n", ret, number_to_recv);
}
for (int i = 0; i < CLIENT_SIZE; i++) {
closesocket(socks[i]);
}
WSACleanup();
}
SOCKET create_socket()
{
SOCKET cli_sock;
struct sockaddr_in addr;
if ((cli_sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
printf("Create Socket Failed::%d\n", GetLastError());
return -1;
}
//inet_pton
memset(addr.sin_zero, 0x00, 8);
addr.sin_family = AF_INET;
inet_pton(AF_INET, IP_ADDRESS, (void*)(&addr.sin_addr.s_addr));
addr.sin_port = htons(PORT);
if (connect(cli_sock, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
{
printf("Connect Error::%d\n", GetLastError());
return -1;
}
return cli_sock;
}
void send_data(SOCKET sock)
{
const int SEND_SIZE = BUF_SIZE / 2;
char buf[SEND_SIZE] = { 0 };
memset(buf, 'a', SEND_SIZE);
shuffle_buffer(buf, SEND_SIZE);
if (send(sock, buf, SEND_SIZE, 0) == SOCKET_ERROR)
{
printf("Send Info Error::%d\n", GetLastError());
}
}
void shuffle_buffer(char* buf, size_t size)
{
for (int i = 0; i < size; i++) {
buf[i] += int(rand() % 26);
}
}
Code above is a socket client using select model run on Win10, the problem is after I send data, but I can not receive data(I am sure that server has sent back data), this code below doesn`t run, so what is the problem? Thanks
The first parameter in select is maxfdp, and I know the difference between Win and Unix, so on Windows, this parameter seems not necessary, and I can write data,
but can not receive it.
if (FD_ISSET(socks[i], &fd_read)) {
char buf[BUF_SIZE];
int n = recv(socks[i], buf, BUF_SIZE, 0);
buf[n] = 0;
printf("%s\n", buf);
number_to_recv--;
}
select removes the sockets from the fd_set if they are not readable/writable. You need to add them back in before the next time you call select.
The reason your code can write data is because sockets start out being writable, so they will still be set in fd_write and your code will write data. They don't start out being readable, if no data has been received yet, so they'll be removed from the fd_read set and then your code stops checking whether they are readable.

C non-blocking send not working

I'm trying to send the large amount of data to the server which should accept the data and parse it. So as I know, when you send() the data in blocking mode in one call, it splits data into chunks and then sends the chunks to the target. But I need to mark each chunk with a small identifier in the beginning of the data (let's say I'm placing a header in each chunk), so I decided to use non- blocking send. I thought, when I do non-blocking send, it sends the max the buffer allows and then returns, leaving the chunking work for me, but it seems that's not happening.
My code is:
struct sockaddr_in target;
SOCKET connection = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
target.sin_family = AF_INET;
target.sin_addr.s_addr = inet_addr(host);
target.sin_port = htons(port);
ULONG NonBlock;
NonBlock = 1;
if (ioctlsocket(connection, FIONBIO, &NonBlock) == SOCKET_ERROR)
{
return WSAGetLastError();
}
fd_set write_fds;
FD_ZERO(&write_fds);
FD_SET(connection, &write_fds);
struct timeval tv;
tv.tv_sec=1;
tv.tv_usec=0;
int result = connect(connection,(SOCKADDR*)&target,sizeof(target));
if(result==SOCKET_ERROR)
{
while(true)
{
result= select(connection+1,NULL,&write_fds,NULL,&tv);
printf("connect: result=%d\r\n",result);
if(result== -1)
{
return WSAGetLastError();
}
else break;
}
}
//later on
fd_set write_set;
int bytes_sent= 0;
int total_sent = 0;
int length = 0;
char *tmp = malloc(sizeof(header)+data_size); //data_size is the size of the large buffer
memcpy(tmp,packet,sizeof(header));
memcpy(tmp+sizeof(header),data,data_size);
int result;
FD_ZERO(&write_set);
FD_SET(connection,&write_set);
struct timeval time_out;
time_out.tv_sec=0;
time_out.tv_usec=1500;
while(total_sent < data_size)
{
length= (data_size+sizeof(my_header))-total_sent;
result = select(connection+1,NULL,&write_set,NULL,&time_out);
if(result== SOCKET_ERROR) return -1;
if(result!=0 && FD_ISSET(connection, &write_set))
{
bytes_sent = send(connection,tmp,length,0);
}
if(bytes_sent == SOCKET_ERROR)
{
return SOCKET_ERROR;
}
if(bytes_sent > 0)
{
//here i need to append a header to the new chunk
}
else break;
}
So basically my question is: why the send on non-blocking socket, still blocks and doesn't return after sending the first chunk, and acts just like regular blocking send? What i want to achieve is send() sending one chunk of data of the length that the system allows, so i put the length of the whole data, assuming that non-blocking send will return after sending the first chunk, because the buffer is to big, to be sent as one block.
UPDATE some runnable code:
#include <windows.h>
#include <winsock.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <types.h>
typedef struct hdr{
uint8_t super_id;
}my_header,*pmy_header;
SOCKET connection;
int start_winsock()
{
WSADATA check;
int result = WSAStartup(MAKEWORD(2,2),&check);
return result;
}
int create_connection(char* host,int port)
{
struct sockaddr_in target;
connection = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
target.sin_family = AF_INET;
target.sin_addr.s_addr = inet_addr(host);
target.sin_port = htons(port);
int result = UnblockSocket();
if(result!=0) return WSAGetLastError();
fd_set write_fds;
FD_ZERO(&write_fds);
FD_SET(connection, &write_fds);
struct timeval tv;
tv.tv_sec=1;
tv.tv_usec=0;
result = connect(connection,(SOCKADDR*)&target,sizeof(target));
if(result==SOCKET_ERROR)
{
while(true)
{
result= select(connection+1,NULL,&write_fds,NULL,&tv);
if(result== -1)
{
return WSAGetLastError();
}
else break;
}
}
return 0;
}
int UnblockSocket()
{
ULONG NonBlock;
NonBlock = 1;
if (ioctlsocket(connection, FIONBIO, &NonBlock) == SOCKET_ERROR)
{
return WSAGetLastError();
}
return 0;
}
int SendMyData(pmy_header header,char * data,int data_size)
{
fd_set write_set;
int bytes_sent= 0;
int total_sent = 0;
int length = 0;
char *tmp = malloc(sizeof(my_header)+data_size);
memcpy(tmp,packet,sizeof(my_header));
memcpy(tmp+sizeof(my_header),data,data_size);
int result;
FD_ZERO(&write_set);
FD_SET(connection,&write_set);
struct timeval time_out;
time_out.tv_sec=0;
time_out.tv_usec=1500;
header->super_id=0xdead;
while(total_sent < data_size)
{
length= (data_size+sizeof(my_header))-total_sent;
if(result== SOCKET_ERROR) return -1;
if(result!=0 && FD_ISSET(connection, &write_set))
{
bytes_sent = send(connection,tmp,length,0);
}
printf("bytes sent per iteration=%d\n",bytes_sent);
if(bytes_sent == SOCKET_ERROR)
{
return SOCKET_ERROR;
}
if(bytes_sent > 0)
{
total_sent+= bytes_sent-sizeof(my_header);
tmp = realloc(tmp,sizeof(my_header)+(data_size-total_sent));
memcpy(tmp,header,sizeof(my_header));
memcpy(tmp+sizeof(my_header),data,data_size-total_sent);
}
else break;
}
free(tmp);
return total_sent;
}
int main(int argc, char *argv[])
{
start_winsock();
int result = create_connection("2.2.2.2",88);
if(result!=0) { printf("Cannot connect\n"); return 0; }
pmy_header *header = malloc(sizeof(my_header));
int buf_size = 500000;
char buffer_test[buf_size];
ZeroMemory(buffer_test,buf_size);
int count=0;
for(count;count<buf_size;count++)
{
strcat(buffer_test,"4");
}
result = SendMyData(header,buffer_test,buf_size);
}
send() is not guaranteed to send everything you ask it to send. It may send less. You MUST take the return value into account. If it is less than the amount you requested, you have to call send() again to re-send the remaining bytes, before then sending new bytes. And in the case of non-blocking, you have to take WSAEWOULDBLOCK into account as well.
And you don't put on a header on each chunk that send() sends. You put a header on each chunk you tell send() to send. You do your own chunking, don't worry about the chunking that TCP does internally. That is a network implementation, it does not affect your protocol. The receiver should be paying attention to your chunk headers, calling recv() as many times as needed to receive your full header and data to account for TCPs chunking.
Try something more like this instead:
SOCKET connection = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (connection == INVALID_SOCKET)
{
return WSAGetLastError();
}
ULONG NonBlock = 1;
in result = ioctlsocket(connection, FIONBIO, &NonBlock);
if (result == SOCKET_ERROR)
{
result = WSAGetLastError();
closesocket(connection);
return result;
}
struct sockaddr_in target;
memset(&target, 0, sizeof(target));
target.sin_family = AF_INET;
target.sin_addr.s_addr = inet_addr(host);
target.sin_port = htons(port);
result = connect(connection, (SOCKADDR*)&target, sizeof(target));
if (result == SOCKET_ERROR)
{
result = WSAGetLastError();
if (result != WSAEWOULDBLOCK)
{
closesocket(connection);
return result;
}
fd_set write_fds;
FD_ZERO(&write_fds);
FD_SET(connection, &write_fds);
struct timeval tv;
tv.tv_sec = 5;
tv.tv_usec = 0;
result = select(0, NULL, &write_fds, NULL, &tv);
if (result == SOCKET_ERROR)
{
result = WSAGetLastError();
closesocket(connection);
return result;
}
if (result == 0)
{
closesocket(connection);
return WSAETIMEDOUT;
}
}
char *tmp_data = data;
int data_remaining = data_size;
while (data_remaining > 0)
{
int pkt_data_size = min(data_remaining, 1024); // replace 1024 with whatever maximum chunk size you want...
int pkt_size = sizeof(header) + pkt_data_size;
char *pkt = malloc(pkt_size);
if (!pkt) return -1;
// fill header as needed...
memcpy(pkt+sizeof(header), tmp_data, pkt_data_size);
tmp_data += pkt_data_size;
data_remaining -= pkt_data_size;
char *tmp_pkt = pkt;
while (pkt_size > 0)
{
result = send(connection, tmp_pkt, pkt_size, 0);
if (result == SOCKET_ERROR)
{
result = WSAGetLastError();
if (result != WSAEWOULDBLOCK)
{
free(pkt);
return -1;
}
fd_set write_set;
FD_ZERO(&write_set);
FD_SET(connection, &write_set);
struct timeval time_out;
time_out.tv_sec = 5;
time_out.tv_usec = 0;
result = select(0, NULL, &write_set, NULL, &time_out);
if (result != 1)
{
free(pkt);
return -1;
}
continue;
}
tmp_pkt += result;
pkt_size -= result;
}
free(pkt);
}

libev more then one watcher per fd fails

I can't seem to get working 2 watchers per socket.. Code below doesn't acually works at all, but if i mix up these calls(for ex. call init/set/start for 1 watcher and then for other), i get only 1 watcher working.. Is there something I'm missing badly here...?
I don't think it has anything to do with loops and setup... I have 1 accept loop(default loop) and 1 loop for accepted connections. I tried both, running code below directly after accepting connection on accept loop and via ev_async_send(...) then executing this code from other io loop. Results were same.
Also setting both events on 1 watcher works fine too.
Thank you
ev_init (pSockWatcher->_wW, &CNetServer::send_cb);
ev_init (pSockWatcher->_wR, &CNetServer::recv_cb);
ev_io_set (pSockWatcher->_wW, pSockWatcher->_sd, EV_WRITE );
ev_io_set (pSockWatcher->_wR, pSockWatcher->_sd, EV_READ );
ev_io_start (loop, pSockWatcher->_wR);
ev_io_start (loop, pSockWatcher->_wW);
Well, here is an example with two I/O watchers on one socket fd, which seems to work fine for me. I am using the ev_io_init() function, however, not the ev_init() and ev_set().
#include <ev.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
static struct ev_loop *loop;
static ev_timer timeout_watcher;
static ev_io in_watcher, out_watcher;
static ev_idle idle_watcher;
static int sock_fd;
// socket input watcher
static void in_cb(EV_P_ ev_io *watcher, int revents) {
int r, t;
char buf[1024];
for (t = 0; (r = read(sock_fd, buf, sizeof(buf))) > 0;) {
t += r;
write(STDOUT_FILENO, buf, r); // copy input to stdout
if (buf[r-1] == '\n') break; // operate line-at-a-time
}
fprintf(stderr, "in: count = %d\n", t);
if (r == 0) {
fputs("in: connection closed\n", stderr);
ev_io_stop(loop, &in_watcher); // stop the socket watcher
ev_break(loop, EVBREAK_ALL); // exit the loop
} else if (r < 0) {
perror("read");
}
}
// socket output watcher
static void out_cb(EV_P_ ev_io *watcher, int revents) {
int r, t, lim;
char buf[1024];
ev_io_stop(loop, &out_watcher);
for (t = 0; t < sizeof(buf); t++) {
buf[t] = 'a' + (rand() % 26);
}
for (t = 0, lim = rand() % 10000 + 1000;
(r = write(sock_fd, buf, (lim - t > sizeof(buf)) ? sizeof(buf) : lim - t)) > 0;) {
t += r;
if (t >= lim) break;
}
if (r < 0) {
perror("write");
}
fprintf(stderr, "out: finished sending, count = %d\n", t);
}
static void timeout_cb(EV_P_ ev_timer *watcher, int revents) {
fprintf(stderr, "timeout: now = %f\n", ev_now(loop));
// send a bunch of stuff on the socket when able
ev_io_start (loop, &out_watcher);
}
static void idle_cb(EV_P_ ev_idle *watcher, int revents) {
static long idle_count = 0;
fprintf(stderr, "idle: count = %ld\n", ++idle_count);
sleep(1); // simulate doing stuff
}
int main() {
extern int errno;
int master_fd;
int sock_opt = 1;
int conn_port = 7000;
struct sockaddr_in addr;
socklen_t addrlen;
// **** the following is needed to set up a socket to receive data ****
master_fd = socket(AF_INET, SOCK_STREAM, 0);
if (master_fd == -1) {
perror("socket");
return errno;
}
if (setsockopt(master_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &sock_opt, sizeof(sock_opt)) == -1) {
perror("setsockopt");
return errno;
}
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(conn_port);
addrlen = sizeof(addr);
if (bind(master_fd, (struct sockaddr *) &addr, addrlen) != 0) {
perror("bind");
return errno;
}
if (listen(master_fd, 3) != 0) {
perror("listen");
return errno;
}
fprintf(stderr, "awaiting a connection on port %d\n", conn_port);
sock_fd = accept(master_fd, (struct sockaddr *) &addr, &addrlen);
if (sock_fd == -1) {
perror("accept");
return errno;
}
fputs("in: connection established\n", stderr);
// **** end of socket setup code ****
// define a loop
loop = ev_default_loop(0);
// define a repeating timer
ev_timer_init (&timeout_watcher, timeout_cb, 5.0, 5.0);
ev_timer_start (loop, &timeout_watcher);
// define an idle process
ev_idle_init(&idle_watcher, idle_cb);
ev_idle_start (loop, &idle_watcher);
// define the socket data receiver
ev_io_init(&in_watcher, in_cb, sock_fd, EV_READ);
ev_io_start (loop, &in_watcher);
// define the socket data write complete watcher
ev_io_init(&out_watcher, out_cb, sock_fd, EV_WRITE);
// run the loop
ev_run(loop, 0);
// clean up
close(sock_fd);
close(master_fd);
return 0;
}

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);