winsock always returning -1 on socket - c++

I'm trying to connect to my server on port 69 using winsock2.h. Everything appears to be compiling correctly but in a debugger maincommsock is always equal to -1. I can't seem to figure out why it isn't working, and need help. Not very experienced with socket programming, and not sure what to do now!. Any help will be greatly appreciated.
I'm not 100% sure what else to try. This is basically a function that establishes a connection on a socket, and sets connection to true, so that it can loop until it connects.
int maincommsock;
bool connection = false;
static void establishconn() {
maincommsock = socket(AF_INET, SOCK_STREAM, 0);
if (maincommsock == -1) {
connection = false;
}
//OutputDebugString((LPCSTR)commservers[1]);
/*
struct hostent *host;
if ((host = gethostbyname(SERV_ADDR)) == NULL) {
connection = FALSE;
}
*/
SOCKADDR_IN sockaddr;
sockaddr.sin_port = 69;
sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
//sockaddr.sin_addr.s_addr = *((unsigned long*)host->h_addr);
if (connect(maincommsock, (SOCKADDR *)(&sockaddr), sizeof(sockaddr)) != 1) {
connection = true;
}
}
EDIT
I used WSAStartup, and the error I'm currently getting is No connection could be made because the target machine actively refused it."
EDIT 2
used htons on the port. It says the operation completed successfully but no connections show up on the server
EDIT 3
I'm going to test it on linux, to make sure that it is actually a server side error and not a problem with my code. I'll keep you guys updated.

Your error handling is a bit lacking.
First off, when an error does occur, STOP what you are doing. Right now, you are not stopping, you just move on to the next API call as if no error occured.
Second, your error handling on connect() is wrong. connect() returns 0 on success and -1 on failure, but you are checking its return value for != 1 so you are going to treat successes and failures the same way.
Try this instead:
static SOCKET establishconn(const char *addr, u_short port)
{
SOCKET commsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (commsock == INVALID_SOCKET)
return INVALID_SOCKET;
//OutputDebugStringA(addr);
SOCKADDR_IN sockaddr = {};
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(port);
sockaddr.sin_addr.s_addr = inet_addr(addr);
if (sockaddr.sin_addr.s_addr == INADDR_NONE)
{
struct hostent *host = gethostbyname(addr);
if (!host)
{
closesocket(commsock);
return INVALID_SOCKET;
}
sockaddr.sin_addr.s_addr = *((u_long*) host->h_addr);
}
if (connect(commsock, (SOCKADDR &sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
{
closesocket(commsock);
return INVALID_SOCKET;
}
return commsock;
}
Then you can do this:
WSAStartup(...);
...
SOCKET maincommsock = establishconn("127.0.0.1", 69);
if (maincommsock != INVALID_SOCKET)
{
...
closesocket(maincommsock);
}
...
WSACleanup();

Berkeley sockets require the address and port information to be presented in network byte order. Winsock follows this API:
All of the data in the SOCKADDR_IN structure, except for the address family, must be specified in network-byte-order (big-endian).
Windows Dev Center
Use htons() to convert the port value from host to network byte order.
sockaddr.sin_port = htons(69);
inet_addr() already returns a value in network byte order.

Related

How to detect if a port is already in use server side (in C++ on windows)?

It's certainly a common question, but not in this terms (windows, server side, accept multi connexion).
My goal is to accept to start a server listing on a port for multiple connections only if before that the port is detected "unused".
At the line where I put //HERE..., binddoesn't return a SOCKET_ERROR status as I expected.
Maybe I'm doing something wrong.
How to detect that my port is not in use by some other app?
Here is the status of the port before running (it is used)
netstat -an
TCP 127.0.0.1:2005 0.0.0.0:0 LISTENING
I hope this snippet is sufficent to explain what I'm doing, it's a merge of several steps.
WSADATA WSAData;
int err = WSAStartup(MAKEWORD(2, 2), &WSAData);
SOCKADDR_IN sin;
socklen_t recsize = sizeof(sin);
int one = 1;
SOCKADDR_IN* csin;
SOCKET csock = INVALID_SOCKET;
socklen_t crecsize = sizeof(SOCKADDR_IN);
int sock_err;
if (m_socket != INVALID_SOCKET)
{
memset(&sin, 0, recsize);
if(m_blocal)
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
else
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_family = AF_INET;
sin.sin_port = htons(m_iPort);
setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(int));
sock_err = bind(m_socket, (SOCKADDR*)&sin, recsize);
//HERE I want to be sure no one else runs on this port
//rest of the code using: select(m_socket + 1, &rd, &wr, &er, &timeout);
}
closesocket(m_socket);
WSACleanup();
Don't set SO_REUSEADDR. Then bind() will fail if the address is already in use and WSAGetLastError() will return WSAEADDRINUSE.
Also note that two processen can still bind to the same port if the IP addresses are different, for example, one process binding to localhost and another process binding to the LAN network address.

Reading from UDP socket over WiFi always timeout

I have a piece of code that send a UDP broadcast to scan for device on our local network. It works fine when im plugged via ethernet, but it doesnt when im connected via WiFi.
Is there something different to do to connect in UDP when using WiFi?
You can find the code im using below. When using WiFi, select always return 0
struct sockaddr_in addr;
//Create socket
if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
{
perror("socket");
exit(1);
}
/* set up destination address */
memset((char *)&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(48620);
addr.sin_addr.s_addr = inet_addr("192.168.3.255");
//TRYING TO BIND, NOT WORKING
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
{
int a = WSAGetLastError(); //ERROR 10049
perror("bind"); //Says NO ERROR
}
//allow broadcast
int broadcast = 1;
if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*)&broadcast, sizeof(broadcast)) == -1)
exit(1);
if (sendto(fd, (const char *)&request, sizeof(request), 0, (struct sockaddr *) &addr, sizeof(addr)) < 0)
{
perror("sendto");
exit(1);
}
do
{
FD_ZERO(&rdFs);
FD_SET(fd, &rdFs);
lTimeout.tv_sec = 1;
lTimeout.tv_usec = 000000;
lSelRet = select(fd, (fd_set*)&rdFs, NULL, NULL, &lTimeout);
if (lSelRet > 0 && FD_ISSET(fd, &rdFs))
{
addrFromSize = sizeof(addrFrom);
lResult = recvfrom(fd, bufferIn, sizeof(bufferIn), 0, (struct sockaddr *) &addrFrom, &addrFromSize);
//Treat result
}
} while (lSelRet > 0);
Note : Even using WiFi, i can estalbish a TCP connection and communicate with the device, its just the UDP broadcast that doesnt work
Note2: currently testing on windows, but I will port it to Linux after
Edit : added the SO_BROADCAST as advised by Remy
Finally got it working, it was a code issue, not a router issue.
The issue was a misuse of the bind function, I needed to use my IP and not the broadcast IP.
/* set up destination address */
memset((char *)&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(48620);
addr.sin_addr.s_addr = inet_addr("192.168.3.134"); //<== Windows : My IP, not the broadcast IP
addr.sin_addr.s_addr = INADDR_ANY; //Linux
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
{
perror("bind");
}
EDIT : strangely enough, in windows you must bind to the ip sending the request, and on linux you must bind to INADDR_ANY.

WSAGetLastError returns WSAENOTSOCK - Cause?

I have something like this in my code
WSADATA wsadata;
int error = WSAStartup(0x0202, &wsadata);
SOCKADDR_IN target; //Socket address information
target.sin_family = AF_INET; // address family Internet
target.sin_port = htons (5005);
target.sin_addr.s_addr = inet_addr ("127.0.0.1");
clntSocket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); //Create socket
if (::connect(clntSocket, (SOCKADDR *)&target, sizeof(target)) == SOCKET_ERROR)
{
//Could not connect
__debugbreak();
}
else
{
//Connected - Now receive data
do
{
char my_stream[800];
iResult = recv(clntSocket,my_stream,sizeof(my_stream),0);
if(iResult<0)
{
int a = WSAGetLastError();
//Receives 10038 - WSAENOTSOCK
}
} while( iResult > 0 );
}
And I would sometimes (occasionally) get 10038. Which states that
Socket operation on nonsocket.
An operation was attempted on something that is not a socket. Either the socket handle parameter did not reference a valid socket,or for select, a member of an fd_set was not valid.
Am I doing something wrong while setting up the socket ? Any suggestions on how to fix the problem ?
Either:
You never opened the socket.
You have corrupted the handle value.
You have closed the socket and then continued to use it.

Read from socket freeze

I have problem while reading data from client on server. The read() function will always freeze (block) after all data are readed and waiting for more data what is undesirable for me.
Server program:
soc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = INADDR_ANY;
bind(soc, (struct sockaddr*) &sin, sizeof(sin));
if (listen(soc, MAX))
return;
int socc; // socket for clinet
while (1) {
if ((socc = accept(soc, (struct sockaddr *) &sin, sinlen)) < 0)
break;
while ((result = read(socc, pointer, SIZE)) > 0) {
// after the data are readed, read function will block
}
// do some stuff and write reply to client => will never done
}
Client program:
...
soc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
struct sockaddr_in socketAddr;
socketAddr.sin_family = AF_INET;
socketAddr.sin_port = htons(port);
memcpy(&(socketAddr.sin_addr), host->h_addr, host->h_length);
if (connect(soc, (sockaddr *)&socketAddr, sizeof(socketAddr)) == -1)
return;
if (write(soc, req.c_str(), strlen(req.c_str())) < 0)
return;
The main problem is that I don't know how much data will be client sending to server, so the server should read all data from socket and after nothing is coming, leave the reading cycle. But the server read whole message for example (30 bytes) and waiting for more (but no more is coming). The sockets are still opened because the client is waiting for reply from server.
You will need to make your socket non-blocking. The read will immediately exit in that case if there is nothing to be read with a specific error.
Look at C- Unix Sockets - Non-blocking read
As stated earlier use non blocking or add RCV_TIMEOUT to socket.
struct timeval tv;
tv.tv_sec = 30; /* 30 Secs Timeout */
setsockopt(sockid, SOL_SOCKET, SO_RCVTIMEO,(struct timeval *)&tv,sizeof(struct timeval));

c++ winsock server-client remote connection

I am trying to create a simple app that exchanges messages between two remote computers.
With the "127.0.0.1" ip it works properly, waits for the client's confirm and connects to the client, but if I try a local "192.168.0.15" or my global ip with the same port, the server connects immediately to sth without waiting for the client.
Here's part of my server code:
char ip[20] = "127.0.0.1"; int port = 19385;
SOCKET sockListen, sockConnect;
SOCKADDR_IN address;
sockConnect = socket (AF_INET, SOCK_STREAM, NULL);
address.sin_addr.s_addr = inet_addr (ip);
address.sin_family = AF_INET;
address.sin_port = htons (port);
sockListen = socket (AF_INET, SOCK_STREAM, NULL);
bind (sockListen, (SOCKADDR*)&address, AddressSize);
listen (sockListen, SOMAXCONN);
sockConnect = accept (sockListen, (SOCKADDR*)&address, &AddressSize);
...
Please suggest how to fix the problem. thx
You are not supposed to initialize your sockConnect variable with socket() before calling accept(). accept() returns a new allocated socket handle that is already connected to a client. You are leaking the socket handle that socket() allocated.
You can only bind() to an IP that belongs to a NIC of the local machine that the app is running on. You cannot bind() to an external IP.
The code you have shown is not doing any error handling at all. You need to add that, eg:
int errCode;
SOCKET sockListen = socket (AF_INET, SOCK_STREAM, NULL);
if (sockListen == INVALID_SOCKET)
{
errCode = WSAGetLastError();
// ...
}
else
{
SOCKADDR_IN address = {0};
address.sin_addr.s_addr = inet_addr (ip);
address.sin_family = AF_INET;
address.sin_port = htons (port);
if (bind (sockListen, (SOCKADDR*)&address, sizeof(address)) == SOCKET_ERROR)
{
errCode = WSAGetLastError();
// ...
}
else
{
if (listen (sockListen, SOMAXCONN) == SOCKET_ERROR)
{
errCode = WSAGetLastError();
// ...
}
else
{
int addressSize;
SOCKET sockClient = accept (sockListen, (SOCKADDR*)&address, &addressSize);
if (sockClient == INVALID_SOCKET)
{
errCode = WSAGetLastError();
// ...
}
else
{
// ...
closesocket(sockClient);
}
}
}
closesocket(sockListen);
}