Click to See Complete Forum and Search --> : Simple Client Server app issue


Cpp_Noob
June 14th, 2009, 04:21 PM
i have a simple client and server application and i want to send a "hello" message from client to server but the i cant seem to get it right , and also when i close the client i cant reconnect back
The server also take ages to close , dunno if its the loop in the new thread that cousing this
can any1 see whats the problem with tis simple code?


Server code (Win32)


#include <windows.h>
#include <winsock.h>

#pragma comment(lib,"wsock32.lib")
#pragma comment(lib,"mpr.lib")

void sckListen();
void sckRecv();

SOCKADDR Addr;
SOCKET Socket;
DWORD threadId;

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{

WSADATA WsaDat;
if (WSAStartup(MAKEWORD(2,0), &WsaDat) != 0)
{MessageBox(0,L"WSA Initialization failed.",L"",0);}


Socket = socket(AF_INET, SOCK_STREAM, 0);
if (Socket == INVALID_SOCKET)
{MessageBox(0,L"Socket creation failed.",L"",0);}


SOCKADDR_IN SockAddr;
SockAddr.sin_port = 8877;
SockAddr.sin_family = AF_INET;//(TCP/IP)

SockAddr.sin_addr.S_un.S_addr = INADDR_ANY;


if (bind(Socket, (SOCKADDR *)(&SockAddr), sizeof(SockAddr)) == SOCKET_ERROR)
{MessageBox(0,L"Attempt to bind failed.",L"",0);}

listen(Socket, 1);


CreateThread( NULL, 0,(LPTHREAD_START_ROUTINE) sckListen,0, 0, &threadId);
CreateThread( NULL, 0,(LPTHREAD_START_ROUTINE) sckRecv,0, 0, &threadId);


while(true)
{
}

}


void sckListen()
{
SOCKET TempSock = SOCKET_ERROR;

while (true)
{
TempSock = accept(Socket, &Addr, (int *)sizeof(Addr));

if (TempSock !=SOCKET_ERROR)
{
Socket = TempSock;
TempSock = SOCKET_ERROR;
}
}
}


void sckRecv()
{
int RetVal = SOCKET_ERROR;
char String[6]={0};
while (RetVal == SOCKET_ERROR)
{
RetVal = recv(Socket, String, strlen(String) + 1, 0);
if (String[0] != NULL){
MessageBoxA(0,String,String,0);}

if ((RetVal == 0)||(RetVal == WSAECONNRESET)||(RetVal == WSAECONNABORTED))
{
MessageBox(0,L"Connection closed at other end.",L"",0);
break;
}
}
}

Client code (Console)

#include <iostream>
#include <windows.h>
#include <winsock.h>

#pragma comment(lib,"wsock32.lib")
#pragma comment(lib,"mpr.lib")
using namespace std;

void main()
{
WSADATA WsaDat;
if (WSAStartup(MAKEWORD(2,0), &WsaDat) != 0)
{cout << ("WSA Initialization failed.");}

SOCKET Socket;
Socket = socket(AF_INET, SOCK_STREAM, 0);
if (Socket == INVALID_SOCKET)
{printf("Socket creation failed.");}


SOCKADDR_IN SockAddr;
SockAddr.sin_port = 8877;
SockAddr.sin_family = AF_INET;

SockAddr.sin_addr.S_un.S_un_b.s_b1 = 127;
SockAddr.sin_addr.S_un.S_un_b.s_b2 = 0;
SockAddr.sin_addr.S_un.S_un_b.s_b3 = 0;
SockAddr.sin_addr.S_un.S_un_b.s_b4 = 1;

if (connect(Socket, (SOCKADDR *)(&SockAddr), sizeof(SockAddr)) != 0)
{printf("Failed to establish connection with server.");}

char String[] = "hello";
send(Socket,String, strlen(String) + 1, 0);


system("pause");
}

Richard.J
June 15th, 2009, 12:13 PM
one obvious erro is that in your sckListen() function you overwriting your Socket variable with the TempSock. After that, you are no longer able to accept incoming connections because your listening socket has been overwritten.

SockAddr.sin_addr.S_un.S_un_b.s_b1 = 127;
SockAddr.sin_addr.S_un.S_un_b.s_b2 = 0;
SockAddr.sin_addr.S_un.S_un_b.s_b3 = 0;
SockAddr.sin_addr.S_un.S_un_b.s_b4 = 1;

seems overly complicated, try gethostbyname with input param "localhost" or inet_addr( "127.0.0.1" )

What exactly is failing when trying to send the message from the client to the server?

Cpp_Noob
June 15th, 2009, 12:52 PM
so ill just make "Socket" an array and store the new connection into arrays?

this code should MessageBox the data i send from the client if there are not NULL
but i get nothing


char String[6]={0};
while (RetVal == SOCKET_ERROR)
{
RetVal = recv(Socket, String, strlen(String) + 1, 0);
if (String[0] != NULL){
MessageBoxA(0,String,String,0);}

Richard.J
June 15th, 2009, 01:26 PM
well, you might want to leave the sckListen() as part of the main routine, then on each successful connection you start a new thread with the sckRecv() function, passing the new socket to it. But be careful, don't use a local variable as the return code of accept:

SOCKET *TempSock = new SOCKET;

*TempSock = accept(Socket, &Addr, (int *)sizeof(Addr));
CreateThread( NULL, 0,(LPTHREAD_START_ROUTINE) sckListen,TempSock, 0, &threadId);

You would need to make sure to delete the TempSock in your thread routine when your done with it.

This should be the first step.

RetVal = recv(Socket, String, strlen(String) + 1, 0);

is wrong, because strrlen(String) returns 0 as you initialized it to all 0. So you pass 1 as the buffer size. You should be using sizeof(String) here to pass 6 as the buffer size.
Does your call to recv() ever return?

Cpp_Noob
June 15th, 2009, 02:00 PM
now connection in made but the sckRecv() in never called and i still cannot reconnect back


#include <windows.h>
#include <winsock.h>

#pragma comment(lib,"wsock32.lib")
#pragma comment(lib,"mpr.lib")

void sckListen();
void sckRecv(LPVOID TempSock);

SOCKADDR Addr;
SOCKET Socket;
DWORD threadId;


int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{

WSADATA WsaDat;
if (WSAStartup(MAKEWORD(2,0), &WsaDat) != 0)
{MessageBox(0,L"WSA Initialization failed.",L"",0);}


Socket = socket(AF_INET, SOCK_STREAM, 0);
if (Socket == INVALID_SOCKET)
{MessageBox(0,L"Socket creation failed.",L"",0);}


SOCKADDR_IN SockAddr;
SockAddr.sin_port = 8877;
SockAddr.sin_family = AF_INET;//(TCP/IP)

SockAddr.sin_addr.S_un.S_addr = INADDR_ANY;


if (bind(Socket, (SOCKADDR *)(&SockAddr), sizeof(SockAddr)) == SOCKET_ERROR)
{MessageBox(0,L"Attempt to bind failed.",L"",0);}

listen(Socket, 1);

while (true)
{
SOCKET *TempSock = new SOCKET;
*TempSock = accept(Socket, &Addr, (int *)sizeof(Addr));

if (*TempSock !=SOCKET_ERROR)
{
Socket = *TempSock;
CreateThread( NULL, 0,(LPTHREAD_START_ROUTINE) sckRecv,(LPVOID)*TempSock, 0, &threadId);

delete [] TempSock;
}
}

}
void sckRecv(LPVOID TempSock)
{

int RetVal = SOCKET_ERROR;
char String[6]={0};
while (RetVal == SOCKET_ERROR)
{
RetVal = recv((SOCKET)TempSock, String, sizeof(String), 0);

if (String[0] != NULL){

MessageBoxA(0,String,String,0);}

if ((RetVal == 0)||(RetVal == WSAECONNRESET)||(RetVal == WSAECONNABORTED))
{
MessageBox(0,L"Connection closed at other end.",L"",0);
break;
}
}
}

Richard.J
June 15th, 2009, 03:42 PM
you better go and learn some basics.
You are still overwriting your Socket here

Socket = *TempSock;

why do you do that?

And then, you are creating the recv thread, passing the newly accepted socket to it (good),
but the instance later, you delete this socket! What is the poor thread expected to do with an invalid socket?
Then, new and delete are a pair, as well as new[] and delete[].

As I said, more basics are required, and until then, I quit.

No offense,
Richard