Help with code

Started by
6 comments, last by nobodynews 16 years, 6 months ago
This is some code from Ron penton's "Mud game programming" book, i've tried to get it to compile under VS2005, but i keep getting errors.

// Code Block 2.1 - Header Includes
// This code block includes all of the standard Sockets API/Winsock headers
#ifdef WIN32                // Windows 95 and above
    #include "winsock2.h"
    #include "Ws2tcpip.h"
#endif
// End Code Block 2.1 - Header Includes

// Code Block 2.2 - Redefinitions and globals for cross-compatibility
#ifdef WIN32                // Windows 95 and above
    WSADATA g_wsadata;      // Winsock data holder
    #define CloseSocket closesocket
    #define GetSocketError WSAGetLastError
    #define StartSocketLib WSAStartup( MAKEWORD( 2, 2 ), &g_wsadata );
    #define CloseSocketLib WSACleanup();
    #ifndef socklen_t
        typedef int socklen_t;
    #endif
#else                       // UNIX/Linux
    #define CloseSocket close
    #define GetSocketError errno
    #define StartSocketLib {}
    #define CloseSocketLib {}
#endif
// End Code Block 2.2 - Redefinitions and globals for cross-compatibility

#include <iostream>
using namespace std;
int main() {
    int err;
    StartSocketLib;

// BEGIN CODE BLOCK 2.3 - Create a Listening Socket on port 4000
    int sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
    if( sock == -1 ) {
        cout << "Socket creation error!" << endl;
        return 0;
    }
    cout << "Socket created!" << endl;

// create a sockaddr_in for binding, listening on port 4000
    struct sockaddr_in socketaddress;
    socklen_t sa_size = sizeof( struct sockaddr_in );
    socketaddress.sin_family = AF_INET;
    socketaddress.sin_port = htons( 4000 );
    socketaddress.sin_addr.s_addr = htonl( INADDR_ANY );
    memset( &(socketaddress.sin_zero), 0, 8 );

    // bind the socket
    err = bind( sock, (struct sockaddr*)&socketaddress, sa_size );
// listen on the socket
    err = listen( sock, 16 );
    // END CODE BLOCK 2.3 - Create a Listening Socket on port 4000

    // wait for an incomming connection now
    int datasock;
    datasock = accept( sock, (struct sockaddr*)&socketaddress, &sa_size );
// receive data
    char buffer[128];
    err = recv( datasock, buffer, 128, 0 );

    cout << "Data received:" << endl;
    cout << buffer << endl;
shutdown( datasock, 2 );
    CloseSocket( datasock );

    shutdown( sock, 2 );
    CloseSocket( sock );

    CloseSocketLib;
}


And this is the error log i receive:
Quote: ------ Build started: Project: Servv1, Configuration: Debug Win32 ------ Compiling... servv1.cpp c:\servv1\servv1\servv1.cpp(35) : error C2065: 'AF_INET' : undeclared identifier c:\servv1\servv1\servv1.cpp(35) : error C2065: 'SOCK_STREAM' : undeclared identifier c:\servv1\servv1\servv1.cpp(35) : error C2065: 'IPPROTO_TCP' : undeclared identifier c:\servv1\servv1\servv1.cpp(35) : error C3861: 'socket': identifier not found c:\servv1\servv1\servv1.cpp(43) : error C2079: 'socketaddress' uses undefined struct 'main::sockaddr_in' c:\servv1\servv1\servv1.cpp(44) : error C2065: 'socklen_t' : undeclared identifier c:\servv1\servv1\servv1.cpp(44) : error C2146: syntax error : missing ';' before identifier 'sa_size' c:\servv1\servv1\servv1.cpp(44) : error C2065: 'sa_size' : undeclared identifier c:\servv1\servv1\servv1.cpp(44) : error C2027: use of undefined type 'main::sockaddr_in' c:\servv1\servv1\servv1.cpp(43) : see declaration of 'main::sockaddr_in' c:\servv1\servv1\servv1.cpp(45) : error C2228: left of '.sin_family' must have class/struct/union type is 'int' c:\servv1\servv1\servv1.cpp(46) : error C2228: left of '.sin_port' must have class/struct/union type is 'int' c:\servv1\servv1\servv1.cpp(46) : error C3861: 'htons': identifier not found c:\servv1\servv1\servv1.cpp(47) : error C2228: left of '.sin_addr' must have class/struct/union type is 'int' c:\servv1\servv1\servv1.cpp(47) : error C2228: left of '.s_addr' must have class/struct/union c:\servv1\servv1\servv1.cpp(47) : error C2065: 'INADDR_ANY' : undeclared identifier c:\servv1\servv1\servv1.cpp(47) : error C3861: 'htonl': identifier not found c:\servv1\servv1\servv1.cpp(48) : error C2228: left of '.sin_zero' must have class/struct/union type is 'int' c:\servv1\servv1\servv1.cpp(51) : error C3861: 'bind': identifier not found c:\servv1\servv1\servv1.cpp(54) : error C3861: 'listen': identifier not found c:\servv1\servv1\servv1.cpp(59) : error C3861: 'accept': identifier not found c:\servv1\servv1\servv1.cpp(63) : error C3861: 'recv': identifier not found c:\servv1\servv1\servv1.cpp(68) : error C3861: 'shutdown': identifier not found c:\servv1\servv1\servv1.cpp(69) : error C3861: 'close': identifier not found c:\servv1\servv1\servv1.cpp(71) : error C3861: 'shutdown': identifier not found c:\servv1\servv1\servv1.cpp(72) : error C3861: 'close': identifier not found Build log was saved at "file://c:\Servv1\Servv1\Debug\BuildLog.htm" Servv1 - 25 error(s), 0 warning(s) ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Advertisement
Do you have the libraries installed, and linked properly?
Does he suggest a specific compiler to use?
Visit my general programming site to get help, tutorials, as well as get experience by joining projects or making your own - My Site
What libraries?


He has tutorials on how to setup older versions of the compiler on the cd, but my copy of the book is from the library, and they don't have the cd.
I can see two sources of problems for these errors: the winsock2 and Ws2tcpip headers aren't being found (in which case there would be an error stating that that I cannot see and therefore will assume that isn't the problem) or you don't define WIN32. That is, if you don't have a setting somewhere that defines WIN32 then the headers you need will not be included. These headers define the missing identifiers.

Let me explain futher: the code
#ifdef WIN32  #include <winsock2.h>  #include <Ws2tcpip>#endif


will not be compiled into your source file if that WIN32 can't be found. So now the question is: how to get WIN32 exists? It should probably be done automatically if you selected the correct project type (Win32 Application, I believe).

However, to narrow down the problem I would first try compiling again after getting rid of the #ifdef and #endif preprocessor directives. If the problem is a case of missing header files then you will continue to have those errors. If the problem is the wrong project type, then you will not get those errors but "undefined symbol" errors. And if the problem is something else then it is probably either the code being written for an obsolete compiler or your compiler settings are otherwise screwed up.

My money is on you selecting the wrong project type or having compiler settings screwed up though.

Hope this helps somehow.

C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!

Alright, now i get a different error. Here is the current code:

#include "stdafx.h"#include "win32pMUD.h"#include "winsock2.h"#include "Ws2tcpip.h"// Code Block 2.2 - Redefinitions and globals for cross-compatibility          // Windows 95 and above    WSADATA g_wsadata;      // Winsock data holder    #define CloseSocket closesocket    #define GetSocketError WSAGetLastError    #define StartSocketLib WSAStartup( MAKEWORD( 2, 2 ), &g_wsadata );    #define CloseSocketLib WSACleanup();    #ifndef socklen_t        typedef int socklen_t;// End Code Block 2.2 - Redefinitions and globals for cross-compatibility#include &lt;iostream&gt;using namespace std;int main() {    int err;    StartSocketLib;// BEGIN CODE BLOCK 2.3 - Create a Listening Socket on port 4000    int sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );    if( sock == -1 ) {        cout &lt;&lt; "Socket creation error!" &lt;&lt; endl;        return 0;    }    cout &lt;&lt; "Socket created!" &lt;&lt; endl;// create a sockaddr_in for binding, listening on port 4000    struct sockaddr_in socketaddress;    socklen_t sa_size = sizeof( struct sockaddr_in );    socketaddress.sin_family = AF_INET;    socketaddress.sin_port = htons( 4000 );    socketaddress.sin_addr.s_addr = htonl( INADDR_ANY );    memset( &(socketaddress.sin_zero), 0, 8 );    // bind the socket    err = bind( sock, (struct sockaddr*)&socketaddress, sa_size );// listen on the socket    err = listen( sock, 16 );    // END CODE BLOCK 2.3 - Create a Listening Socket on port 4000    // wait for an incomming connection now    int datasock;    datasock = accept( sock, (struct sockaddr*)&socketaddress, &sa_size );// receive data    char buffer[128];    err = recv( datasock, buffer, 128, 0 );    cout &lt;&lt; "Data received:" &lt;&lt; endl;    cout &lt;&lt; buffer &lt;&lt; endl;shutdown( datasock, 2 );    CloseSocket( datasock );    shutdown( sock, 2 );    CloseSocket( sock );    CloseSocketLib;}



And here is the error:
Quote:
------ Build started: Project: win32pMUD, Configuration: Debug Win32 ------
Compiling...
win32pMUD.cpp
c:\win32pmud\win32pmud\win32pmud.cpp(26) : warning C4244: 'initializing' : conversion from 'SOCKET' to 'int', possible loss of data
c:\win32pmud\win32pmud\win32pmud.cpp(49) : warning C4244: '=' : conversion from 'SOCKET' to 'int', possible loss of data
c:\win32pmud\win32pmud\win32pmud.cpp(64) : fatal error C1070: mismatched #if/#endif pair in file 'c:\win32pmud\win32pmud\win32pmud.cpp'
Build log was saved at "file://c:\win32pMUD\win32pMUD\Debug\BuildLog.htm"
win32pMUD - 1 error(s), 2 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
you have the line:

#ifndef socklen_t

but no #endif. Either add the #endif below the next statement or remove the #ifndef. I would first at the #endif and if that didn't work remove the #ifndef

The other warnings can be fixed with a cast or changing the type you are assigning the socket... to a socket.

C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!

Alright, now i get another error.

This is the current code:
#include "stdafx.h"#include "win32pMUD.h"#include "winsock2.h"#include "Ws2tcpip.h"// Code Block 2.2 - Redefinitions and globals for cross-compatibility          // Windows 95 and above    WSADATA g_wsadata;      // Winsock data holder    #define CloseSocket closesocket    #define GetSocketError WSAGetLastError    #define StartSocketLib WSAStartup( MAKEWORD( 2, 2 ), &g_wsadata );    #define CloseSocketLib WSACleanup();	    #ifndef socklen_t	#endif        typedef int socklen_t;// End Code Block 2.2 - Redefinitions and globals for cross-compatibility#include <iostream>using namespace std;int main() {    int err;    StartSocketLib;// BEGIN CODE BLOCK 2.3 - Create a Listening Socket on port 4000    int sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );    if( sock == -1 ) {        cout << "Socket creation error!" << endl;        return 0;    }    cout << "Socket created!" << endl;// create a sockaddr_in for binding, listening on port 4000    struct sockaddr_in socketaddress;    socklen_t sa_size = sizeof( struct sockaddr_in );    socketaddress.sin_family = AF_INET;    socketaddress.sin_port = htons( 4000 );    socketaddress.sin_addr.s_addr = htonl( INADDR_ANY );    memset( &(socketaddress.sin_zero), 0, 8 );    // bind the socket    err = bind( sock, (struct sockaddr*)&socketaddress, sa_size );// listen on the socket    err = listen( sock, 16 );    // END CODE BLOCK 2.3 - Create a Listening Socket on port 4000    // wait for an incomming connection now    int datasock;    datasock = accept( sock, (struct sockaddr*)&socketaddress, &sa_size );// receive data    char buffer[128];    err = recv( datasock, buffer, 128, 0 );    cout << "Data received:" << endl;    cout << buffer << endl;shutdown( datasock, 2 );    CloseSocket( datasock );    shutdown( sock, 2 );    CloseSocket( sock );    CloseSocketLib;}



And this is the error log:
Quote:
------ Build started: Project: win32pMUD, Configuration: Debug Win32 ------
Compiling...
win32pMUD.cpp
c:\win32pmud\win32pmud\win32pmud.cpp(28) : warning C4244: 'initializing' : conversion from 'SOCKET' to 'int', possible loss of data
c:\win32pmud\win32pmud\win32pmud.cpp(51) : warning C4244: '=' : conversion from 'SOCKET' to 'int', possible loss of data
Linking...
win32pMUD.obj : error LNK2019: unresolved external symbol __imp__WSACleanup@0 referenced in function _main
win32pMUD.obj : error LNK2019: unresolved external symbol __imp__closesocket@4 referenced in function _main
win32pMUD.obj : error LNK2019: unresolved external symbol __imp__shutdown@8 referenced in function _main
win32pMUD.obj : error LNK2019: unresolved external symbol __imp__recv@16 referenced in function _main
win32pMUD.obj : error LNK2019: unresolved external symbol __imp__accept@12 referenced in function _main
win32pMUD.obj : error LNK2019: unresolved external symbol __imp__listen@8 referenced in function _main
win32pMUD.obj : error LNK2019: unresolved external symbol __imp__bind@12 referenced in function _main
win32pMUD.obj : error LNK2019: unresolved external symbol __imp__htonl@4 referenced in function _main
win32pMUD.obj : error LNK2019: unresolved external symbol __imp__htons@4 referenced in function _main
win32pMUD.obj : error LNK2019: unresolved external symbol __imp__socket@12 referenced in function _main
win32pMUD.obj : error LNK2019: unresolved external symbol __imp__WSAStartup@8 referenced in function _main
MSVCRTD.lib(crtexew.obj) : error LNK2019: unresolved external symbol _WinMain@16 referenced in function ___tmainCRTStartup
C:\win32pMUD\Debug\win32pMUD.exe : fatal error LNK1120: 12 unresolved externals
Build log was saved at "file://c:\win32pMUD\win32pMUD\Debug\BuildLog.htm"
win32pMUD - 13 error(s), 2 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Those errors mean you aren't linking with the appropriate library. The names are mangled, but it's easy to figure out the real function: remove the beginning underscore and remove everything after the @ symbol. This leaves WSACleanup. Doing a Google search of this function gives the first link from msdn2. At the bottom of the page is a list of requirements that need to be met to use the function. You are missing the library. Link the library and all errors associated with winsock should disappear. You may need to do similar things with the Ws2tcpip library. To link:

Click Project->project name Properties. Next to Configuration is a drop-down box: select "All Configurations". Next, select Configuration Properties->Linker->Input

And enter in the library files you should have found the way I did. Hope that helps

edit: I forgot to mention, if you had copied and pasted that first error:

"error LNK2019: unresolved external symbol __imp__WSACleanup@0 referenced in function _main" into Google the first result basically says what I said: link the library file. "Unresolved extern symbol" errors are all because you declared something, but never defined it. That is, you included the header file(which had the declarations) but didn't link the library file (which had the definitions).

C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!

This topic is closed to new replies.

Advertisement