Link to home
Start Free TrialLog in
Avatar of MellowD0c
MellowD0c

asked on

Debugging simple Winsock2 Client

Here is what i have for the client so far. How can i extract the port # off the commandline? The way i am doing this is what i have seen in most examples online, but somehow it gives me error. Also i saw in many places that are using:

int main(int argc, char **argv) instead of int main(int argc, char *argv)

a '**' to argv, and i am wondering what it does? If i use just one pointer it gives me this error:

client.cpp(40): error C2664: 'atoi' : cannot convert parameter 1 from 'char' to 'const char *'
        Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast


Second Question:

If i compile the below code, it gives me this error while/after Linking, and how could i fix it?

Unhandled exception at 0x00467b99 in CSsock.exe: 0xC0000005: Access violation reading location 0x00000000.

and it points to atox.c file (i believe this has to do with my atoi(port) converter.

All i want from this client is to be able to just connect to server by the mentioned port on the commandline, send messages  and recieve them as well. More like really simple chat client.


//
// client.cpp


#include <stdio.h>
#include <iostream>
#include <winsock2.h>
#include <conio.h>

#define HOSTNAMELEN 128


using namespace std;

////////////////////////////////////////////////////////////

int main(int argc, char **argv)
{
      
      
      struct hostent *host;
      char buffer[100];
      int result;
      if (argc > 1 )
      {
            
            cerr << "Syntax: server PortNumber" <<endl;
            exit (1);
      }
      
      
      WORD wVersionRequested = MAKEWORD(2,2);
      WSADATA wsaData;
      if(WSAStartup(wVersionRequested, &wsaData)!=0)
      {
            cerr << "Process failed on Winsock startup" << endl;
            ExitProcess(0);
      }

      int Port = atoi(argv[1]);
      SOCKADDR_IN theSrvr;
      char serverHostName[HOSTNAMELEN];
      result = gethostname(serverHostName, HOSTNAMELEN);
      
      host = gethostbyname(serverHostName);
      if (result == SOCKET_ERROR)
      {
            result = WSAGetLastError();
            cerr << "Error Occured  " << result << endl;
                  exit (1);
      }
      
      
      ZeroMemory(&theSrvr, sizeof(SOCKADDR_IN));
      theSrvr.sin_family = AF_INET;
      theSrvr.sin_port = htons((u_short)Port);
      
      CopyMemory(&theSrvr.sin_addr, host->h_addr_list[0], host->h_length);


      SOCKET skt = socket(AF_INET, SOCK_STREAM, 0);
      if (skt == INVALID_SOCKET)
      {
            result = WSAGetLastError();
            cerr << "Error Occured  " << result << endl;
            WSACleanup();
            exit (1);
      }
  int len = sizeof(theSrvr);
      getsockname(skt, (SOCKADDR *) &theSrvr, &len);
      u_short actual_port = ntohs(theSrvr.sin_port);
      //
      //connect
      //
      result = connect(skt, (const SOCKADDR *) &theSrvr, sizeof(theSrvr));
      
      if (result == SOCKET_ERROR)
      {
            result = WSAGetLastError();
            cerr << "Error Occured  " << result << endl;
            closesocket(skt);
            exit (1);
      }

      


      //
      // Find the server
      //
   // LPHOSTENT lpHostEntry;

//      lpHostEntry = gethostbyname(theSrvr);
   
      // Show the port number
      //
      cout <<"============================================================="<<endl;
      cout <<"============================================================="<<endl;
      cout <<"======================TALK Client============================"<<endl;
      cout <<"============Connecting on Port: " << Port << endl;
      cout <<"============================================================="<<endl;
      cout <<"============================================================="<<endl;
      

SOCKET remoteSocket;
while (true)
 {
       memset(buffer, 0, sizeof(buffer));
            if(_kbhit()){
                        int bytesRead = send(remoteSocket, buffer, sizeof(buffer), 0);


                        if (-1 == bytesRead)
                              {
                              cout << "Socket Error" << endl;
                              break;
                              }
                        else if (0 == bytesRead)
                              {
                              cout << "Socket closed on other side" << endl;
                              break;
                              }
                        else
                              {
                              buffer[bytesRead] = '\0';
                              cout << "<" << buffer << endl;
                              recv(remoteSocket, buffer, sizeof(buffer)-1, 0);
                        Sleep(500);
                              }
            }
  }
      //
      // Close BOTH sockets before exiting
      //
      closesocket(remoteSocket);
      closesocket(skt);
      

      //
      // Release WinSock
      //
      WSACleanup();
return 0;
}


Avatar of DanRollins
DanRollins
Flag of United States of America image

>>int main(int argc, char **argv)

argv is a char** (pointer to a character pointer).  It is more often expressed as:

    int main(int argc, char* argv[])

which is the same thing, but is more easily read as "an array of pointers to char" or "an array of C-style strings".

Anyway, all it means is that you can cycle through each of the command-line arguments as follows:

for (int j=0; j< argc, j++ ) {
     printf("parm %d is %s", j, argv[j] );
     if ( strcmp(argv[j],"/DELETE") == 0 ) {
         // recieved a parameter of /DELETE
         // so take notice!
     }
}
-==-=-=-=-=-=-=-=-=-=-=-
as to the error... you are not verifying that there is a valid argv[1] before calling atoi.  Use code like:

if (argc > 1) {  // argv[0] and argv[1] are valid
     printf("parm 1 is %s", argv[1] );
}

-- Dan
Avatar of MellowD0c
MellowD0c

ASKER

Thanks, I modified that part, but appears to me that my send() and recv() functions aren't working. My client does connect but it disconnects after establishing a successful connection. Can you tell what am i doing wrong in the following code? I want to make it send and receive messages and exit only if someone types exit in the start of line....

//
// Client.cpp


#include <stdio.h>
#include <iostream>
#include <winsock2.h>
#include <conio.h>

#define HOSTNAMELEN 128


using namespace std;

////////////////////////////////////////////////////////////

int main(int argc, char *argv[])
{
      
      
      struct hostent *host;
      char buffer[1024];// for send()
      char xbuffer[1024];      // for recv()
          
      int result;
      int Port=0;

      while (--argc)
      {
            if (argc == 1)
            {
                  Port = atoi(argv[1]);
            }
            if (argc > 2 )
            {
                        
                  cerr << "Syntax: server PortNumber" <<endl;
                        exit (1);
            }
      }
      //Set Winsock Version #
      WORD wVersionRequested = MAKEWORD(2,2);
      WSADATA wsaData;
      if(WSAStartup(wVersionRequested, &wsaData)!=0)
      {
            cerr << "Process failed on Winsock startup" << endl;
            ExitProcess(0);
      }

      
      SOCKADDR_IN theSrvr;
      char serverHostName[HOSTNAMELEN];
      result = gethostname(serverHostName, HOSTNAMELEN);
      //
      // Find the server
      //
   
      host = gethostbyname(serverHostName);
      if (host == NULL) {
            cerr << " Error Occured: " << WSACleanup() <<endl;
                        
                  }

      
      
      ZeroMemory(&theSrvr, sizeof(SOCKADDR_IN));
      theSrvr.sin_family = AF_INET;
      theSrvr.sin_port = htons((u_short)Port);
      
      CopyMemory(&theSrvr.sin_addr, host->h_addr_list[0], host->h_length);


      SOCKET skt = socket(AF_INET, SOCK_STREAM, 0);
      if (skt == INVALID_SOCKET)
      {
            result = WSAGetLastError();
            cerr << "Error Occured  while making Socket " << result << endl;
            WSACleanup();
            exit (1);
      }
      //SOCKET remoteSocket;
  int len = sizeof(theSrvr);
      getsockname(skt, (SOCKADDR *) &theSrvr, &len);
      u_short actual_port = ntohs(theSrvr.sin_port);
      //
      //connect
      //
      result = connect(skt, (const SOCKADDR *) &theSrvr, sizeof(theSrvr));
      
      if (result == SOCKET_ERROR)
      {
            result = WSAGetLastError();
            cerr << "Error Occured while connection  " << result << endl;
            closesocket(skt);
            exit (1);
      }

      
   
      // Show the port number
      //
      cout <<"============================================================="<<endl;
      cout <<"============================================================="<<endl;
      cout <<"======================TALK Client============================"<<endl;
      cout <<"============Connecting on Port: " << Port << endl;
      cout <<"============================================================="<<endl;
      cout <<"============================================================="<<endl;
      


while (true)
{
       memset(buffer, 0, sizeof(buffer));
            if(_kbhit())
            {
                        int bytesRead = send(skt, buffer, sizeof(buffer), 0);

                        if (-1 == bytesRead)
                              {
                              cout << "Socket Error" << endl;
                              break;
                              }
                        else if (0 == bytesRead)
                              {
                              cout << "Socket closed on other side" << endl;
                              break;
                              }
                        else
                              {
                              buffer[bytesRead] = '\0';
                              cout << "<" << buffer << endl;
                              recv(skt, xbuffer, sizeof(xbuffer)-1, 0);
                              cout << ">" << xbuffer << endl;
                              memset(xbuffer, 0, sizeof(xbuffer));
                        Sleep(500);
                              }
            }
}
      closesocket(skt);
      // Release WinSock
      WSACleanup();
return 0;
}
ASKER CERTIFIED SOLUTION
Avatar of DanRollins
DanRollins
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial