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?
Related
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'am trying to set my own timeot for connect() function.
my code works well with default connection like this:
bool connectFUNC4(char * ipaddr) {
WSADATA wsa;
struct sockaddr_in server;
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
return false;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
return false;
server.sin_addr.s_addr = inet_addr(ipaddr);
server.sin_family = AF_INET;
server.sin_port = htons(5577);
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0)
return false;
return true;
}
I understand idea with blocking and not blocking connection, and I've found solution with setting to nonblocking mode and timeout. It always finished successful but communication does not work.
bool connectFUNC3(char * ipaddr) {
WSADATA wsa;
struct sockaddr_in server;
server.sin_addr.s_addr = inet_addr(ipaddr);
server.sin_family = AF_INET;
server.sin_port = htons(5577);
unsigned long block = 1;
ioctlsocket((unsigned int)sock, FIONBIO, &block);
WSAGetLastError();
int ret = connect(sock, (struct sockaddr *)&server, sizeof(server));
timeval time_out;
time_out.tv_sec = 5;
time_out.tv_usec = 0;
fd_set setW, setE;
FD_ZERO(&setW);
FD_SET(sock, &setW);
FD_ZERO(&setE);
FD_SET(sock, &setE);
select(0, NULL, &setW, &setE, &time_out);
bool flag;
if (FD_ISSET(sock, &setW))
{
// connection successful
flag = true;
}
else if (FD_ISSET(sock, &setE))
{
// connection fail
flag = false;
}
else
{
// connection timeout
flag = false;
}
block = 0;
ioctlsocket((unsigned int)sock, FIONBIO, &block);
return flag;
}
Please help to make it work, or to find another solution (multithread not usable in my case). Thank you.
Neither of your functions are checking ANY return values for errors. And when calling select() in non-blocking mode, call it only if connect() fails with a WSAEWOULBLOCK error, and if select() then returns > 0 then you should be checking setE first and not setW.
Try something more like this:
void closesock(SOCKET *s)
{
// preserve current error code
int err = WSAGetLastError();
closesocket(*sock);
*sock = INVALID_SOCKET;
WSASetLastError(err);
}
bool connectFUNC4(char * ipaddr)
{
// you really shouldn't be calling WSAStartup() here.
// Call it at app startup instead...
struct sockaddr_in server = {0};
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(ipaddr);
server.sin_port = htons(5577);
// ipaddr valid?
if (server.sin_addr.s_addr == INADDR_NONE)
return false;
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
return false;
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
// connection failed
closesock(&sock);
return false;
}
// connection successful
return true;
}
bool connectFUNC3(char * ipaddr)
{
// you really shouldn't be calling WSAStartup() here.
// Call it at app startup instead...
struct sockaddr_in server = {0};
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(ipaddr);
server.sin_port = htons(5577);
// ipaddr valid?
if (server.sin_addr.s_addr == INADDR_NONE)
return false;
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
return false;
// put socked in non-blocking mode...
u_long block = 1;
if (ioctlsocket(sock, FIONBIO, &block) == SOCKET_ERROR)
{
closesock(&sock);
return false;
}
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
// connection failed
closesock(&sock);
return false;
}
// connection pending
fd_set setW, setE;
FD_ZERO(&setW);
FD_SET(sock, &setW);
FD_ZERO(&setE);
FD_SET(sock, &setE);
timeval time_out = {0};
time_out.tv_sec = 5;
time_out.tv_usec = 0;
int ret = select(0, NULL, &setW, &setE, &time_out);
if (ret <= 0)
{
// select() failed or connection timed out
closesock(&sock);
if (ret == 0)
WSASetLastError(WSAETIMEDOUT);
return false;
}
if (FD_ISSET(sock, &setE))
{
// connection failed
int err = 0;
getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, sizeof(err));
closesock(&sock);
WSASetLastError(err);
return false;
}
}
// connection successful
// put socked in blocking mode...
block = 0;
if (ioctlsocket(sock, FIONBIO, &block) == SOCKET_ERROR)
{
closesock(&sock);
return false;
}
return true;
}
I can't figure out how to accept multiple connections for a simple tcp server using winsock.
I've tried a couple different ways and I can't figure out how to get another connection to work. The first call to accept() seems to be the only one that works. Can someone provide a simple example of how to do this or explain what's going on with listen() and accept() here?
#include <string>
#include <Winsock2.h>
WSADATA WsaData;
unsigned char packet_in[64];
unsigned short port = 29992;
unsigned int max_packet_size = sizeof(packet_in);
sockaddr_in xaddress;
SOCKET sock;
SOCKET sock1 = INVALID_SOCKET;
SOCKET sock2 = INVALID_SOCKET;
int main()
{
int r = WSAStartup( MAKEWORD(2,2), &WsaData );
xaddress.sin_family = AF_INET;
xaddress.sin_port = htons(port);
DWORD nonBlocking = 1;
sockaddr_in from;
int fromLength = sizeof( from );
int count = 0;
sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
r = bind(sock, (const sockaddr*) &xaddress, sizeof(sockaddr_in));
if (r != 0) printf("%d\n", WSAGetLastError());
r = listen(sock, SOMAXCONN);
if (r == SOCKET_ERROR)
printf("%d\n",WSAGetLastError());
ioctlsocket(sock, FIONBIO, &nonBlocking);
while(true)
{
if(count == 0)
{
sock1 = accept(sock, NULL, NULL);
}
else if (count == 1)
{
sock2 = accept(sock, NULL, NULL);
}
if(sock1 != INVALID_SOCKET)
count = 1;
if(sock2 != INVALID_SOCKET)
count = 2;
printf("%i\n",count);
}
return 0;
}
I don't know how to network programming on Windows, but it basically looks like on Linux, so this is small example for Linux.
struct sockaddr_in server_addr
socklen_t len = sizeof(server_addr);
...
while(1)
{
struct sockaddr_in client_addr;
int client_fd;
if((client_fd = accept(server_sock, (struct sockaddr*)& client_addr, &len)) < 0)
{
cerr<<"accept() error"<<endl;
continue;
}
...
}
There is full example written in Polish, but you should understand:
full example (find //server.c)
Main differences between network programming on Windows and Linux are structures and classes, so it should give you some knowledge: Beej's guide to network programming
I think from this simple program, You will get better idea :)
// Multi-Client - Server chat application
#include"header.h"
void isr(int n)
{
printf("Client is Disconnected ..\n");
kill(getpid(),9);
return;
}
main()
{
int sockfd,nsfd,len,pid,size;
char buffer[500],buffer1[500];
struct sockaddr_in server;
///////////////////////////////////////////////////////////////////////
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd==0)
{
printf("Socket file is not created socket is fail...\n");
return;
}
////////////////////////////////////////////////////////////////////////
server.sin_family=AF_INET;
server.sin_port=htons(9898);
len = sizeof(server);
/////////////////////////////////////////////////////////////////////
bind(sockfd,(struct sockaddr*)&server,len);
perror("bind");
/////////////////////////////////////////////////////////////
listen(sockfd,5);
perror("listen");
/////////////////////////////////////////////////////////////////
bzero(buffer,sizeof(buffer));
zero(buffer1,sizeof(buffer1));
//////////////////////////////////////////////////////////////////////
while(1)
{
nsfd=accept(sockfd,(struct sockaddr *)&server,&len);
if(nsfd<0)
{
perror("accept");
return;
}
if(fork()==0)
{
while(1)
{
size=recv(nsfd,buffer,sizeof(buffer),0);
if(size==0)
{
printf("Server is Disconnected...\n");
return;
}
printf("Data:%s\n",buffer);
bzero(buffer,sizeof(buffer));
}
}
else
{
printf("Enter the massage:\n");
signal(17,isr);
while(1)
{
gets(buffer);
send(nsfd,buffer,strlen(buffer)+1,0);
bzero(buffer,sizeof(buffer));
}
}
}
}
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;
}
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.