Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Debugging simple Winsock2 Client

Posted on 2003-03-16
3
Medium Priority
?
322 Views
Last Modified: 2013-12-03
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;
}


0
Comment
Question by:MellowD0c
  • 2
3 Comments
 
LVL 49

Expert Comment

by:DanRollins
ID: 8150562
>>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
0
 

Author Comment

by:MellowD0c
ID: 8155937
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;
}
0
 
LVL 49

Accepted Solution

by:
DanRollins earned 240 total points
ID: 8156139
>>I want to make it send and receive messages and exit only if someone types exit in the start of line....

You need to plan what you want to do and then do it.  The code that's there simply doesn't do anything like what you say you want it to do.  For instance, pretend to be a computer and see what will happen the first time though the while loop.

1) clear the buffer to all zeros
2) if there has been a kestroke..
3)     send 1024 bytes of 0 to the host
4)     detect error
5)     display a misleading message
6)     skip the else because it can't happen
7)     Do nothing for 1/2 second
8) go back to step one and repeat

First, please read up on the send() function, you'll see that it is not used to receive data from the remote host.  That would be a start.

Next, remove the kbhit() and the while loop.  Just do some simple tests.  Send a string, and then use Sleep to wait a few seconds and use recv() to read the first few bytes of whatever the host has sent.

Use the debugger to single-step through the code, and be sure to examine variables in the variable window.

-- Dan
0

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article describes a technique for converting RTF (Rich Text Format) data to HTML and provides C++ source that does it all in just a few lines of code. Although RTF is coming to be considered a "legacy" format, it is still in common use... po…
What my article will show is if you ever had to do processing to a listbox without being able to just select all the items in it. My software Visual Studio 2008 crystal report v11 My issue was I wanted to add crystal report to a form and show…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …

577 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question