views:

181

answers:

4

Hi, im just starting to learn about sockets and i have been given this code, and i have to make the port lookup logic work. But the problem is i keep getting this run time error and I dont know why?

// portlookup.cpp
// Given a service name, this program displays the corresponding port number.

#include <iostream>
#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
using namespace std;

int main (int argc, char **argv)
{
    char    service[80];    // This string contains name of desired service
    struct  servent *pse;   // pointer to service information entry
    short   port;           // Port # (in Network Byte Order) of desired service

    if (argc < 2)
    {
        cout << "Please specify a service." << endl;

    }

    strcpy_s(service, sizeof(service), argv[1]);

    WORD wVersion = 0x0202;
    WSADATA wsaData;
    int iResult = WSAStartup(wVersion, &wsaData);  // Returns zero if successful
    if (iResult != 0) {
        cout << "Insufficient resources to startup WINSOCK." << endl;
        return 0;
    }

    port = htons( (u_short) atoi(service)); // 1st try to convert string to integer
    if (port == 0) {                        // if that doesn't work, call service function
        pse = getservbyname(service,NULL);
        if (pse) {
            port = pse->s_port;
        }
        else
        {
            cout << "Invalid service request." << endl;
            return INVALID_SOCKET;
        }
    }

    cout << "Service: " << service << endl;
    cout << "Port:    " << htons(port) << endl;

}
+2  A: 

You need to start your program with an argument. The line strcpy_s(service, sizeof(service),argv[1]); assumes you've given the program 1 argument, which will be stored in argv[1].

If you don't run it with any arguments, argv[1] will be NULL and your program will crash.

nos
+1  A: 

Make sure to exit if no parameter is specified.

if (argc < 2) 
{ 
    cout << "Please specify a service." << endl; 
    return 0; // exit! 
} 
mnemosyn
+3  A: 

Your problem appears to be that you aren't passing a command line, you check argc < 2, but when it is < 2 you execute the strcpy_s anyway.

In Visual Studio, Got to the Project Properties dialog, from there go to the Debugging page and add the service name to Command Arguments

And fix your argument checking code

if (argc < 2)
{
    //cout << "Please specify a service." << endl;
    cerr << "error: no service specified." << endl;
    return EXIT_FAILURE; // return some non-zero value to indicate failure.
}
John Knoeller
Do they still teach command line in school?
Richard Pennington
@Richard: No idea. back in my day vi was the _advanced_ editor. and debugging was printf ;D
John Knoeller
@John: You mean that vi *isn't* the advanced editor? When did emacs win?
Richard Pennington
@Richard: emacs? we didn't have emacs, we had vi and ed.
John Knoeller
EXIT_FAILURE or 1 make better default return codes than 42. :)
Roger Pate
@Roger: is there a standard exit code for 'your not using me right?'
John Knoeller
@John: The C and C++ standards only provide EXIT_SUCCESS and EXIT_FAILURE. Either 1 or 2 is commonly used for that (2 slightly more common), but there's no consensus common enough for me to say it's standard.
Roger Pate
While you're at it, using stderr (cerr/clog) for those error messages is better than stdout. :P
Roger Pate
A: 

also,

port = htons( (u_short) atoi(service));
...
cout << htons(port);
just somebody