I am working on a client-server application where I have two different ports, one (principal) for us send and receive messages or any other order, and another one to send and receive screenshots of the server to the client. From client to server notice to start us send'll catch and showing in a new window ... works fine but if I close the window and open it again then and I can not connect to that port (bind fails me).
MY question is how do I clean or completely release the port I use for screenshots without affecting the main port, that is, when you close the window to release the port as if I had never used and advise the client to do the same.
Here I leave the code:
Server:
int serviceCapture(int port)
{
int error;
WSAData wsaDataER;
error = WSAStartup(MAKEWORD(2, 2), &wsaDataER);
if (error == SOCKET_ERROR)
{
return 1;
}
// ShowMessage ("Server: WinSocket Started Correctly!\n");
sock_ER = socket(AF_INET, SOCK_STREAM, 0);
if (sock_ER == SOCKET_ERROR)
{
return 2;
}
struct sockaddr_in escritorioRem; // New! Our network socket structure
escritorioRem.sin_family = AF_INET; // Always have ti as this for internet
escritorioRem.sin_port = htons(puerto); // Dont forget the byte ordering
escritorioRem.sin_addr.s_addr = INADDR_ANY;internet
if(!enviandoCapturas){
error = bind(sock_ER, (sockaddr*)&escritorioRem, sizeof(escritorioRem)); // Attempt to bind the socket
if (error == SOCKET_ERROR)
{
return 3 ;
}
}
error = listen(sock_ER, 1); // Listen for connections
if (error == SOCKET_ERROR)
{
return 4;
}
// }
//ShowMessage ( "Server: Waiting for a client to connect ...\n"); // Just to keep us up to date - ish
int len= sizeof (struct sockaddr);
sock_ER=accept(sock_ER,(sockaddr*)&escritorioRem, &len);
//
//do{
if( sock_ER<0){
return 5;
}
sendingCaps=true;
startSendCaps();
return 0;
}
Client:
int client(string serv, int puerto)
{
int error;
WSAData wsaData;
error = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (error == SOCKET_ERROR)
{
return 1;
}
// ShowMessage( "Client: WinSocket Loaded.\n");
if (sock == SOCKET_ERROR)
{
return 2;
}
// ShowMessage( "Client: Socket Opened Successfully!\n");
const char *server_name = serv.c_str(); // The server name we will connect to
struct hostent *host_entry; // Translates into something the computer can understand
host_entry = gethostbyname(server_name); // Gather out information
if (host_entry == NULL)
{
return 3;
}
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons((unsigned short) puerto);
server.sin_addr.s_addr = *(unsigned long*) host_entry->h_addr;
if(connect(ventanaCliente->sock, (sockaddr*)&server, sizeof(struct sockaddr))<0){
return 4;
}
receivingCaps=true;
strartReceiveCaps();
return 0;
}
Related
I created two win32 server c++ projects both will do similar task like listen for IPC connection from client. both will listen in different port numbers like 1000 and 2000, I'm able to connect first started application like 1000 or 2000 but not both, every second connection request will through timeout at client side.
Below I added my client and server code, I have two server applications with different port no (1000 and 2000) and two client applications which connect to 1000 and 2000 port server app.
Both server apps will go for listening mode but one only take connection request another will throw timeout at client application. if any suggestion please update your comments.
Client Code :
void Initialize()
{
WSADATA WSAData;
WSAStartup(MAKEWORD(2, 2), &WSAData);
}
SOCKET CloseSocket(SOCKET _Socket)
{
/*A shutdown() closes SOCK_STREAM sockets gracefully. Both processes can acknowledge that they are no longer sending. OR Disable sends and/or receives on a socket*/
shutdown(_Socket,SD_BOTH);
/*The closesocket function closes an existing socket.*/
closesocket(_Socket);
return _Socket = INVALID_SOCKET;
}
SOCKET Connect( SOCKET _Socket,
SOCKADDR_IN _Addres )
{
int connectResult = connect(_Socket,(struct sockaddr *)&_Addres,sizeof(_Addres));
if(connectResult == SOCKET_ERROR)
{
_Socket = CloseSocket(_Socket);
}
else if(connectResult == ETIMEDOUT)
{
_Socket = CloseSocket(_Socket);
}
return _Socket;
}
SOCKET ClientSocketPipline(SOCKET _Socket)
{
/*Socket types are defined in sys/socket.h. These types--SOCK_STREAM, SOCK_DGRAM, or SOCK_RAW--are supported by AF_INET and AF_UNIX. The following creates a stream socket in the Internet domain:*/
if ((_Socket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
return _Socket = CloseSocket(_Socket);
}
struct timeval timeout;
memset(&timeout,0,sizeof(timeout));
timeout.tv_sec = 2;
timeout.tv_usec = 0;
if ( setsockopt (_Socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0 &&
setsockopt (_Socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0 )
{
return _Socket = CloseSocket(_Socket);
}
return _Socket;
}
void ClientConnectionCall()
{
SOCKET ConnectSocket;
ConnectSocket = INVALID_SOCKET;
ConnectSocket = ClientSocketPipline(ConnectSocket);
SOCKADDR_IN SocketAddres;
memset(&SocketAddres,0,sizeof(SocketAddres));
/*Convert IPv4 and IPv6 addresses from text to binary form*/
if(inet_pton(AF_INET,"192.160.1.1", &SocketAddres.sin_addr.s_addr)>0)
{
SocketAddres.sin_port = htons(1000); // and 2000
SocketAddres.sin_family = AF_INET;
ConnectSocket = Connect(ConnectSocket, SocketAddres);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Initialize();
ClientConnectionCall();
return 0;
}
Server Code listener (Port no : 1000) :
SOCKET ServerClass::CloseSocket(SOCKET _Socket)
{
/*A shutdown() closes SOCK_STREAM sockets gracefully. Both processes can acknowledge that they are no longer sending. OR Disable sends and/or receives on a socket*/
shutdown(_Socket,SD_BOTH);
/*The closesocket function closes an existing socket.*/
closesocket(_Socket);
return _Socket = INVALID_SOCKET;
}
SOCKET ServerClass::Bind(SOCKET _Socket, SOCKADDR_IN _Address)
{
/*bind : Associate a local address with a socket.*/
if(::bind(_Socket,(struct sockaddr*)&_Address,sizeof(_Address)) == SOCKET_ERROR)
{
_Socket = CloseSocket(_Socket);
}
return _Socket;
}
SOCKET ServerClass::ServerSocketPipline(SOCKET _Socket,int _Type)
{
/*Socket types are defined in sys/socket.h. These types--SOCK_STREAM, SOCK_DGRAM, or SOCK_RAW--are supported by AF_INET and AF_UNIX. The following creates a stream socket in the Internet domain:*/
if ((_Socket = socket(AF_INET, _Type, 0)) < 0)
{
return _Socket = CloseSocket(_Socket);
}
int opt = 1;
/* Set socket keep connections alive */
if (setsockopt(_Socket,SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) == SOCKET_ERROR)
{
return _Socket = CloseSocket(_Socket);
}
return _Socket;
}
SOCKET ServerClass::CreateSocket(SOCKET _Socket, int _Port)
{
_Socket = INVALID_SOCKET;
_Socket = ServerSocketPipline(_Socket, SOCK_STREAM);
SOCKADDR_IN SocketAddres;
memset(&SocketAddres,0,sizeof(SocketAddres));
SocketAddres.sin_addr.s_addr = htonl(INADDR_ANY);
SocketAddres.sin_port = htons(_Port);
SocketAddres.sin_family = AF_INET;
//Associate a local address with a socket.
_Socket = Bind( _Socket, SocketAddres );
/*Establish a socket to listen for incoming connection*/
if(::listen(_Socket, 5) != SOCKET_ERROR)
{
//Socket listen success.
}
else
{
//Socket listen failed.
_Socket = SOCKET_ERROR;
}
return _Socket;
}
DWORD WINAPI ServerClass::SocketListener(LPVOID threadParam)
{
if(threadParam != NULL)
{
ServerClass *thisClass = (ServerClass *)threadParam;
SOCKET tempSocket = INVALID_SOCKET;
socklen_t addrlen = sizeof(struct sockaddr_in);
SOCKADDR_IN SocketAddres;
memset(&SocketAddres,0,sizeof(SocketAddres));
SocketAddres.sin_addr.s_addr = htonl(INADDR_ANY);
SocketAddres.sin_port = htons(1000);
SocketAddres.sin_family = AF_INET;
if(thisClass->m_BindSock != INVALID_SOCKET)
{
/*Accept a connection on a socket.*/
tempSocket = ::accept( thisClass->m_BindSock, (struct sockaddr*)&SocketAddres, &addrlen);
if(tempSocket != INVALID_SOCKET)
{
SetEvent(thisClass->m_SocketThreadHandle);
}
else
{
tempSocket = thisClass->CloseSocket(tempSocket);
SetEvent(thisClass->m_SocketThreadHandle);
}
}
}
return 0;
}
ServerClass::ServerMainCall(void)
{
Initialize();
m_BindSock = CreateSocket(m_BindSock,1000);
m_SocketThreadHandle = CreateThread(NULL, 0, SocketListener, this, 0, NULL);
WaitForSingleObject(m_SocketThreadHandle,INFINITE);
int msgboxID = MessageBox( NULL, L"Connection request received from first client", L"",
MB_ICONEXCLAMATION | MB_OK );
}
Server Code listener (Port no : 2000) :
SOCKET ServerClass::CloseSocket(SOCKET _Socket)
{
/*A shutdown() closes SOCK_STREAM sockets gracefully. Both processes can acknowledge that they are no longer sending. OR Disable sends and/or receives on a socket*/
shutdown(_Socket,SD_BOTH);
/*The closesocket function closes an existing socket.*/
closesocket(_Socket);
return _Socket = INVALID_SOCKET;
}
SOCKET ServerClass::Bind(SOCKET _Socket, SOCKADDR_IN _Address)
{
/*bind : Associate a local address with a socket.*/
if(::bind(_Socket,(struct sockaddr*)&_Address,sizeof(_Address)) == SOCKET_ERROR)
{
_Socket = CloseSocket(_Socket);
}
return _Socket;
}
SOCKET ServerClass::ServerSocketPipline(SOCKET _Socket,int _Type)
{
/*Socket types are defined in sys/socket.h. These types--SOCK_STREAM, SOCK_DGRAM, or SOCK_RAW--are supported by AF_INET and AF_UNIX. The following creates a stream socket in the Internet domain:*/
if ((_Socket = socket(AF_INET, _Type, 0)) < 0)
{
return _Socket = CloseSocket(_Socket);
}
int opt = 1;
/* Set socket keep connections alive */
if (setsockopt(_Socket,SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) == SOCKET_ERROR)
{
return _Socket = CloseSocket(_Socket);
}
return _Socket;
}
SOCKET ServerClass::CreateSocket(SOCKET _Socket, int _Port)
{
_Socket = INVALID_SOCKET;
_Socket = ServerSocketPipline(_Socket, SOCK_STREAM);
SOCKADDR_IN SocketAddres;
memset(&SocketAddres,0,sizeof(SocketAddres));
SocketAddres.sin_addr.s_addr = htonl(INADDR_ANY);
SocketAddres.sin_port = htons(_Port);
SocketAddres.sin_family = AF_INET;
//Associate a local address with a socket.
_Socket = Bind( _Socket, SocketAddres );
/*Establish a socket to listen for incoming connection*/
if(::listen(_Socket, 5) != SOCKET_ERROR)
{
//Socket listen success.
}
else
{
//Socket listen failed.
_Socket = SOCKET_ERROR;
}
return _Socket;
}
DWORD WINAPI ServerClass::SocketListener(LPVOID threadParam)
{
if(threadParam != NULL)
{
ServerClass *thisClass = (ServerClass *)threadParam;
SOCKET tempSocket = INVALID_SOCKET;
socklen_t addrlen = sizeof(struct sockaddr_in);
SOCKADDR_IN SocketAddres;
memset(&SocketAddres,0,sizeof(SocketAddres));
SocketAddres.sin_addr.s_addr = htonl(INADDR_ANY);
SocketAddres.sin_port = htons(2000);
SocketAddres.sin_family = AF_INET;
if(thisClass->m_BindSock != INVALID_SOCKET)
{
/*Accept a connection on a socket.*/
tempSocket = ::accept( thisClass->m_BindSock, (struct sockaddr*)&SocketAddres, &addrlen);
if(tempSocket != INVALID_SOCKET)
{
SetEvent(thisClass->m_SocketThreadHandle);
}
else
{
tempSocket = thisClass->CloseSocket(tempSocket);
SetEvent(thisClass->m_SocketThreadHandle);
}
}
}
return 0;
}
ServerClass::ServerMainCall(void)
{
Initialize();
m_BindSock = CreateSocket(m_BindSock,2000);
m_SocketThreadHandle = CreateThread(NULL, 0, SocketListener, this, 0, NULL);
WaitForSingleObject(m_SocketThreadHandle,INFINITE);
int msgboxID = MessageBox( NULL,L"Connection request received from second client",L"",
MB_ICONEXCLAMATION | MB_OK);
}
Finally found the answer to the problem. The issue is because of the firewall blocking at server machine side. After disable it, things started working, for more details please go to the below link:
What can be the reasons of connection refused errors?
For my project I am unable to debug the program so i cannot be sure as to why this error occurs.
My server, which is hosted on c# is failing to connect to server on localhost.
Instead of it sending back a "connection" signal to my server, it never connects, I think the code is written well and I can't see any errors, maybe i made a careless mistake somewhere
Also, I HAVE to use gethostbyname instead of getaddrinfo
winsock namespace:
SOCKET WinSock::ConnectToServer(PCHAR IP, USHORT Port)
{
WSADATA WSA;
if (WSAStartup(MAKEWORD(2, 0), &WSA))
{
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s != SOCKET_ERROR)
{
hostent *Host = gethostbyname(IP);
if (Host != ERROR)
{
SOCKADDR_IN Addr;
Addr.sin_family = AF_INET;
Addr.sin_port = htons(Port);
Addr.sin_addr.s_addr = NULL;
if (bind(s, PSOCKADDR(&Addr), sizeof(Addr)) > 0)
{
return s;
}
}
}
}
return FALSE;
}
BOOL WinSock::SendData(SOCKET s, PBYTE Packet)
{
DWORD PacketSize = lstrlenA(PCHAR(Packet));
if (send(s, PCHAR(&PacketSize), 8, 0) > NULL)
{
if (send(s, PCHAR(Packet), PacketSize, 0) > NULL)
{
return TRUE;
}
}
return FALSE;
}
main method:
int main()
{
char key = 1;
SOCKET S = WinSock::ConnectToServer(0, 55480);
while(true)
{
WinSock:SendData(S, (PBYTE)key);
}
}
if (bind(s, PSOCKADDR(&Addr), sizeof(Addr)) > 0)
The description of this code is that it is supposed to connect to a server. But the problem is that bind() does not connect to any server. It only links the socket to a local port. This is what servers that listen on sockets do. This is, presumably, the same port that the server already opened, hence the bind() fails. If the server wasn't listening bind() will, ironically, succeed. But it won't be connect to anything, anyway.
You want to use connect() and not bind().
Additionally, I have to note that if this function creates a socket first, but then fails to establish a connection for this or any other reason it will return an error indication but fail to close the socket, thus leaking a socket descriptor. You must fix this bug, too.
You are not actually making a connection to the server. You are calling bind() to bind the client socket to a local port 55480, but that does not create a connection. You need to instead call connect() to connect the client socket to the remote port 55480.
Also, your SendData() is coded wrong. It is telling send() to send 8 bytes for the PacketSize, but a DWORD is only 4 bytes in size. And send() does not return NULL on failure. And send() is not guaranteed to send all of the requested bytes, so you need to call it in a loop. And it is customary to send multi-byte integers in network byte order (big endian).
Also, you have coded SendData() to expect a null-terminated C-style string, but that is not what your main() is actually passing in to it.
Try something more like this:
bool WinSock::Init()
{
WSADATA WSA;
return (WSAStartup(MAKEWORD(2, 0), &WSA) == 0);
}
bool WinSock::Cleanup()
{
return (WSACleanup() == 0);
}
SOCKET WinSock::ConnectToServer(const char *IP, unsigned short Port)
{
hostent *Host = gethostbyname(IP);
if ((Host != NULL) && (Host->h_addrtype == AF_INET)
{
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s != INVALID_SOCKET)
{
SOCKADDR_IN Addr = {};
Addr.sin_family = AF_INET;
Addr.sin_port = htons(Port);
Addr.sin_addr.s_addr = * (u_long*) Host->h_addr;
if (connect(s, PSOCKADDR(&Addr), sizeof(Addr)) != SOCKET_ERROR)
{
return s;
}
closesocket(s);
}
}
return INVALID_SOCKET;
}
bool WinSock::Close(SOCKET s)
{
return (closesocket(s) == 0);
}
bool WinSock::SendData(SOCKET s, const void* Data, DWORD DataSize)
{
const char *ptr = (const char*) Data;
while (DataSize > 0)
{
int numSent = send(s, ptr, DataSize, 0);
if (numSent == SOCKET_ERROR) return false;
ptr += numSent;
DataSize -= numSent;
}
return true;
}
bool WinSock::SendData(SOCKET s, const char *Packet)
{
DWORD PacketSize = lstrlenA(Packet);
DWORD tmp = htonl(PacketSize);
if (!SendData(s, &tmp, sizeof(tmp)) return false;
return SendData(s, Packet, PacketSize);
}
int main()
{
if (WinSock::Init())
{
const char *key = "1";
SOCKET S = WinSock::ConnectToServer(NULL, 55480);
if (s != INVALID_SOCKET)
{
while (true)
{
WinSock:SendData(S, key);
}
WinSock::Close(s);
}
WinSock::Cleanup();
}
return 0;
}
I've bumped into a problem with my broadcasting server. basically, I want it to send broadcasts continuously from the moment I launch it. for some reason it will not start until it receives a connection from somewhere. I must have messed up something but I can't realise what.
here is my code:
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
SOCKET sock;
sock = socket(AF_INET, SOCK_DGRAM, 0);
char broadcast = 'a';
if(setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0)
{
perror("broadcast options");
closesocket(sock);
return 1;
}
struct sockaddr_in Recv_addr;
struct sockaddr_in Sender_addr;
int len = sizeof(struct sockaddr_in);
char recvBuff[50];
int recvBuffLen = 50;
//char sendMsg[] = "broadcast message from salam rofl";
Recv_addr.sin_family = AF_INET;
Recv_addr.sin_port = htons(PORT);
Recv_addr.sin_addr.s_addr = INADDR_ANY;
if(bind(sock, (sockaddr*)&Recv_addr, sizeof(Recv_addr)) < 0)
{
perror("bind");
_getch;
closesocket(sock);
return 1;
}
//recvfrom(sock, recvBuff, recvBuffLen, 0, (sockaddr *)&Sender_addr, &len);
//cout << "\nreceived message: " << recvBuff;
while(1)
{
Sleep(3000);
//_getch();
getTime();
if(sendto(sock, currentTime, strlen(currentTime)+1, 0, (sockaddr *)&Sender_addr, sizeof(Sender_addr)) < 0)
{
perror("borhot send: ");
_getch();
closesocket(sock);
return 0;
}
else cout << "message sent successfully";
}
_getch;
closesocket(sock);
WSACleanup();
return 0;
basically if I remove recvfrom, it will give me a send error ("No error") which simply puzzles me. also, if I send it something with a client, it will start broadcasting, but if I connect with another client, only the first client is receiving the broadcast.
thank you in advance.
I doubt it matters but I'm trying to broadcast the current time.
You are not initializing Sender_Addr so you are not telling sendto() where to actually broadcast to.
Try this instead:
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET)
{
perror("socket creation");
_getch;
return 1;
}
BOOL enabled = TRUE;
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&enabled, sizeof(BOOL)) < 0)
{
perror("broadcast options");
_getch;
closesocket(sock);
return 1;
}
struct sockaddr_in Sender_addr;
Sender_addr.sin_family = AF_INET;
Sender_addr.sin_port = htons(BROADCAST_PORT);
Sender_addr.sin_addr.s_addr = inet_addr("Broadcast IP Here");
struct sockaddr_in Recv_addr;
Recv_addr.sin_family = AF_INET;
Recv_addr.sin_port = htons(PORT);
Recv_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (sockaddr*)&Recv_addr, sizeof(Recv_addr)) < 0)
{
perror("bind");
_getch;
closesocket(sock);
return 1;
}
while(1)
{
Sleep(3000);
getTime();
if (sendto(sock, currentTime, strlen(currentTime)+1, 0, (sockaddr *)&Sender_addr, sizeof(Sender_addr)) < 0)
{
perror("borhot send: ");
_getch();
closesocket(sock);
return 0;
}
cout << "message sent successfully";
}
_getch;
closesocket(sock);
WSACleanup();
return 0;
Looks like your Sender_addr is never being initialized, thus when you remove the recvfrom you're getting an error, and when the recvfrom is in place it's getting populated with the address of the first client to connect (but never being updated).
If you don't know the addresses of the clients that you want to broadcast to, you'll need to setup some handshake where they send you a ping, you receive it with recvfrom, and you store their address in a list or something. Then, when you broadcast, you need to send your message to every client address in the list.
back again (sorry)
I've created a socket C++ application, but it isn't working properly.
This is my first code:
void Network::Start()
{
this->socket = Env::GetSocket();
SOCKADDR_IN sInformation;
sInformation.sin_family = AF_INET;
sInformation.sin_addr.s_addr = INADDR_ANY;
sInformation.sin_port = htons(30000);
bind(this->socket, (SOCKADDR*) (&sInformation), sizeof(sInformation));
listen(this->socket, 10);
while (true)
{
this->DO();
}
}
And the DO function:
void Network::DO()
{
SOCKET s = SOCKET_ERROR;
sockaddr_in sock_addr;
accept(s, (sockaddr*) &sock_addr, NULL);
if (INVALID_SOCKET == s)
{
return;
}
else
{
cout << "Received connection from " << inet_ntoa(sock_addr.sin_addr);
}
}
What happens, always (even if I connect) the value s is INVALID_SOCKET. I connect via a .SWF but it doesn't accept my connection. What am I doing wrong?
You are not doing adequate error handling, and you are not using accept() correctly. Try this:
void Network::Start()
{
this->socket = Env::GetSocket();
if (this->socket == INVALID_SOCKET)
{
// error
return;
}
SOCKADDR_IN sInformation = {0};
sInformation.sin_family = AF_INET;
sInformation.sin_addr.s_addr = INADDR_ANY;
sInformation.sin_port = htons(30000);
if (bind(this->socket, (SOCKADDR*) &sInformation, sizeof(sInformation)) != 0)
{
// error
return;
}
if (listen(this->socket, 10) != 0)
{
// error
return;
}
while (true)
{
this->DO();
}
}
void Network::DO()
{
SOCKADDR_IN sock_addr = {0};
socklen_t sock_addr_len = sizeof(sock_addr);
SOCKET s = accept(this->socket, (SOCKADDR*) &sock_addr, &sock_addr_len);
if (INVALID_SOCKET == s)
{
return;
}
cout << "Received connection from " << inet_ntoa(sock_addr.sin_addr);
// use s as needed. Don't forget to call close(s) or closesocket(s)
// when finished, depending on your platform...
}
accept takes the listening socket as a parameter, and returns the newly connected socket;
socklen_t length = sizeof(sockaddr_in);
s = accept(this->socket, (sockaddr*) &sock_addr, &length);
EDIT: Just tested the program, with the socket created with AF_INET, SOCK_STREAM and sInformation cleared out;
bzero((char *) &sInformation, sizeof(sInformation));
...it seems to be running well on MacOS X and linux.
I use following code to check if a port is available or not:
bool ClassA::CheckPortTCP(short int dwPort , char *ipAddressStr)
{
struct sockaddr_in client;
int sock;
client.sin_family = AF_INET;
client.sin_port = htons(dwPort);
client.sin_addr.S_un.S_addr = inet_addr(ipAddressStr);
sock = (int) socket(AF_INET, SOCK_STREAM, 0);
int result = connect(sock, (struct sockaddr *) &client,sizeof(client));
// change to result == 0 -> failure in writing code too quick ;-)
if (result = 0) return true; // port is active and used
else return false;
}
The problem is if the port is opened but not connected the check failed! How can I easily examine that the port is available (not listening, not connected)?
e.g. port 21111 (output of netstat) -> my function doesn't recognize that the port is not free
TCP 0.0.0.0:21111 xxxxDUMMYxxxx:0 LISTENING
Thx
You have two errors: The first is that in the if statement you assign zero to result. The other is that connect returns -1 on failure to connect, and a non-negative value if it manages to connect.
There is also a problem that if you manage to connect, you don't close that connection.
the line client.sin_addr.S_un.S_addr = inet_addr(ipAddressStr); can not work for me. change it to:
bool CheckPortTCP(short int dwPort, char *ipAddressStr)
{
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup function failed with error: %d\n", iResult);
return false;
}
struct sockaddr_in client;
int sock;
client.sin_family = AF_INET;
client.sin_port = htons(dwPort);
client.sin_addr.s_addr = inet_addr(ipAddressStr);
sock = (int)socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET) {
wprintf(L"ERROR: Socket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return false;
}
printf("INFO: Checking Port : %s:%d\n", ipAddressStr, dwPort);
int result = connect(sock, (struct sockaddr *) &client, sizeof(client));
if (result == SOCKET_ERROR) {
printf("ERROR: %s", WSAGetLastError());
WSACleanup();
return false;
}
else
{
WSACleanup();
closesocket(sock);
return true;
}
}