int getPort(sockaddr_in a){
//return ntohs(a.sin_port);
int port;
port = htons(a.sin_port);
return port;
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WSADATA wsaData;
int error;
std::string strIP;
error = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (error != NO_ERROR)
{ // there was an error
dbg_ostream << "(Setup) ERROR WSAStartup.\n";
return -1;
}
if (wsaData.wVersion != 0x0202)
{ // wrong WinSock version!
dbg_ostream << "(Setup) ERROR WSAStartup.\n";
WSACleanup (); // unload ws2_32.dll
return -1;
}
SOCKET s=socket(AF_INET,SOCK_DGRAM,0); //open a UDP socket for use
si.sin_family=AF_INET;
// Set the socket I/O mode: In this case FIONBIO
// enables or disables the blocking mode for the
// socket based on the numerical value of iMode.
// If iMode = 0, blocking is enabled;
// If iMode != 0, non-blocking mode is enabled.
u_long iTrue = 1;
u_long iFalse = 0;
u_long iMode = 1;
int err = ioctlsocket(s,FIONBIO,&iMode);
char buffer[50];
int br;
int fromlen = sizeof(sockaddr_in) ;
char *str1="abc\0";
char *str2="def\0";
if(TYPE == CLIENT)
{
///////////////////////////////////////////////////////////////////////
// Client
///////////////////////////////////////////////////////////////////////
dbg_ostream << "(Client) Acting as client ...\n";
// set the Boolean option SO_BROADCAST to true
setsockopt(s,SOL_SOCKET,SO_BROADCAST, (char*)&iTrue, sizeof(int) );
si.sin_addr.s_addr=htonl(INADDR_BROADCAST);
si.sin_port = htons(5000);
error = sendto(s, str1, 4, 0, (const sockaddr*)&si, sizeof(sockaddr_in));
if (error == SOCKET_ERROR) {
dbg_ostream << "(Client) ERROR sendto.\n";
WSACleanup (); // unload ws2_32.dll
return -1;
}
int t=timeGetTime();
while(timeGetTime()-t<5000){
br=recvfrom(s, buffer, 50, 0, (sockaddr*)&si, &fromlen); // used si here, since it isn't used anywhere after. Normally, don't do this!
strIP = getHost(si);
if(br!=-1) {
dbg_ostream << "(Client) Got " << buffer << " from " << getHost(si) << ":" << getPort(si) << std::endl;
}
}
closesocket(s);
dbg_ostream << "(Client) Done.\n";
SOCKET ConnectSocket;
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET) {
dbg_ostream << "(Client) Error socket " << WSAGetLastError() << std::endl;
WSACleanup();
return -1;
}
// WSAStartup () has been called
// SOCKET s is valid
// s has been bound to a port using sockaddr_in sock
sockaddr_in target;
target.sin_family = AF_INET; // address family Internet
target.sin_port = htons (5000); // set server’s port number
target.sin_addr.s_addr = inet_addr (strIP.c_str()); // set server’s IP
if ( connect( s, (SOCKADDR*) &target, sizeof(target) ) == SOCKET_ERROR)
{ // an error connecting has occurred!
dbg_ostream << "(Client) Error connect " << WSAGetLastError() << std::endl;
WSACleanup ();
return -1;
}
dbg_ostream << "(Client) Connected to server." << std::endl;
int numBytes;
while (1) {
numBytes = recv (s, buffer, sizeof(buffer), 0);
if (numBytes == SOCKET_ERROR) {
dbg_ostream << "(Client) Error recv " << WSAGetLastError() << std::endl;
WSACleanup();
return -1;
}
else if (numBytes == 0) {
dbg_ostream << "(Client) Connection closed before any data received" << std::endl;
WSACleanup();
return 0;
}
else if (numBytes > 0) {
buffer[numBytes] = '\0';
dbg_ostream << "(Client) Msg received (" << numBytes << ") " << buffer << std::endl;
}
Sleep(50);
}
}
else
{
///////////////////////////////////////////////////////////////////////
// pretend we are a server on port 5000
///////////////////////////////////////////////////////////////////////
dbg_ostream << "(Server) Acting as server ...\n";
si.sin_port = htons(5000);
si.sin_addr.s_addr=htonl(INADDR_ANY);
error = bind(s,(const sockaddr*)&si,sizeof(sockaddr_in));
if (error == SOCKET_ERROR) {
// error
WSACleanup (); // unload WinSock
dbg_ostream << "(Server) ERROR bind\n";
return -1; // quit
}
while(1) {
br=recvfrom(s, buffer, 50, 0, (sockaddr*)&si, &fromlen);
if(br!=-1){
strIP = getHost(si);
dbg_ostream << "(Server) Got " << buffer << " from " << getHost(si) << ":" << getPort(si) << std::endl;
error = sendto(s, str2, 4, 0, (const sockaddr*)&si,sizeof(sockaddr_in)); //we don't need to set up si for the destination because it was just obtained
if (error == SOCKET_ERROR) {
WSACleanup (); // unload ws2_32.dll
dbg_ostream << "(Server) ERROR sendto\n";
return -1;
}
break;
}
Sleep(20);
}
dbg_ostream << "(Server) Done.\n";
SOCKET ListenSocket;
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET) {
dbg_ostream << "(Server) Error socket " << WSAGetLastError() << std::endl;
WSACleanup();
return -1;
}
sockaddr_in sock_in;
sock_in.sin_family = AF_INET;
sock_in.sin_addr.s_addr = inet_addr(strIP.c_str());
sock_in.sin_port = htons(5000);
if (bind( ListenSocket, (SOCKADDR*) &sock_in, sizeof(sock_in)) == SOCKET_ERROR) {
dbg_ostream << "(Server) Error bind " << WSAGetLastError() << std::endl;
closesocket(ListenSocket);
WSACleanup ();
return -1;
}
if (listen(ListenSocket, 5) == SOCKET_ERROR)
{
// error! unable to listen
dbg_ostream << "(Server) Error listen " << WSAGetLastError() << std::endl;
WSACleanup ();
return -1;
}
SOCKET AcceptSocket;
while(1) {
AcceptSocket = SOCKET_ERROR;
while( AcceptSocket == SOCKET_ERROR ) {
AcceptSocket = accept( ListenSocket, NULL, NULL );
}
dbg_ostream << "(Server) Client connected." << std::endl;
ListenSocket = AcceptSocket;
break;
}
// SOCKET s is initialized
std::string msg; // buffer that is 11 characters big
msg = "Hey There!";
int numBytes;
numBytes = send (ListenSocket, msg.c_str(), msg.length(), 0);
if (numBytes == SOCKET_ERROR) {
dbg_ostream << "(Server) Error send " << WSAGetLastError() << std::endl;
WSACleanup();
return -1;
}
else if (numBytes == 0) {
dbg_ostream << "(Server) Connection closed before any data received" << std::endl;
WSACleanup();
return 0;
}
else if (numBytes > 0) {
dbg_ostream << "(Server) Msg sent " << numBytes << " bytes of " << msg.length() << std::endl;
}
}
WSACleanup();
dbg_ostream << "Exiting ...." << std::endl;
return 0;
}
Help with winsock2 connection over LAN - unable to bind
Thank you for any help you are willling to offer. I am unable to bind to a port using my simple server-client code that I slightly modified from code taken from thread titled "Critique my broadcast code". When I run server and client on the same computer, the program functions correctly. However the print statements report that the port number is different on each end. I do not understand why this is. And when I run client and servers on different computers connected via a router I am unable to bind to the port on the server side (WSAEADDRNOTAVAIL error). The program grabs the IP from the UDP packet sent to each computer. It is to this IP address that the server attempts to bind to prior to opening TCP connection. All computers have dynamic IP's. I also am not sure if my router is set up properly for this, although of course it behaves well in all other respects. Below is my code. Log output from the case generating the WSAEADDRNOTAVAIL error is included after the code. Here is output. UDP stuff works fine but I am unable to bind on server side. (Server) Acting as server ... (Server) Got abc from 192.168.1.108:3561 (Server) Done. (Server) Error bind 10049 // WSAEADDRNOTAVAIL results from an attempt to bind to an address that is not valid for the local computer The thread 0x7C4 has exited with code -1 (0xFFFFFFFF). (Client) Acting as client ... (Client) Got def from 192.168.1.105:5000 (Client) Done. (Client) Error connect 10060 // WSAETIMEDOUT The thread 0x740 has exited with code -1 (0xFFFFFFFF).
SOCKET ListenSocket; ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (ListenSocket == INVALID_SOCKET) { dbg_ostream << "(Server) Error socket " << WSAGetLastError() << std::endl; WSACleanup(); return -1; } sockaddr_in sock_in; sock_in.sin_family = AF_INET; sock_in.sin_addr.s_addr = inet_addr(strIP.c_str()); sock_in.sin_port = htons(5000); if (bind( ListenSocket, (SOCKADDR*) &sock_in, sizeof(sock_in)) == SOCKET_ERROR) { dbg_ostream << "(Server) Error bind " << WSAGetLastError() << std::endl; closesocket(ListenSocket); WSACleanup (); return -1; }
your are binding the socket to the remote IP :S why?
That is a good question. Thank you for pointing that out.
I made the following change and it now seems to work:
//sock_in.sin_addr.s_addr = inet_addr(strIP.c_str());
sock_in.sin_addr.s_addr = htonl(INADDR_ANY);
I assume this is the right thing to do.
thanks!
I made the following change and it now seems to work:
//sock_in.sin_addr.s_addr = inet_addr(strIP.c_str());
sock_in.sin_addr.s_addr = htonl(INADDR_ANY);
I assume this is the right thing to do.
thanks!
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement