Forum: PC-Programmierung Windows: socket starten (Visual Studio 2008)


von brechbunkt (Gast)


Lesenswert?

Hallo,

ich arbeite mich gerade ich winsock Programmierung ein und möchte das 
Socket starten. Hierfür habe ich einfach nur eine kurze Funktion, die 
ich dann in der main aufrufen möchte.

Hier die entsprechende Datei:
1
/* avoid conflicts by incuding windows.h bevore winsock2.h */
2
#ifndef WIN32_LEAN_AND_MEAN
3
#define WIN32_LEAN_AND_MEAN
4
#endif
5
6
7
/*___ includes _______________________________________________________________*/
8
#include <windows.h>
9
#include <winsock2.h>
10
#include <stdio.h>
11
12
13
/*___ functions ______________________________________________________________*/
14
/* start socket */
15
int startWinsock(void)
16
{
17
    WSADATA wsa;
18
    return WSAStartup(MAKEWORD(2,0),&wsa);
19
}


Hier erhalte ich nun aber diesen Fehler:
1
1>Kompilieren...
2
1>stdafx.cpp
3
1>Kompilieren...
4
1>socket.cpp
5
1>winsock_console.cpp
6
1>AssemblyInfo.cpp
7
1>Code wird generiert...
8
1>Ressourcen werden kompiliert...
9
1>Microsoft (R) Windows (R) Resource Compiler Version 6.0.5724.0
10
1>Copyright (C) Microsoft Corporation.  All rights reserved.
11
1>Verknüpfen...
12
1>socket.obj : error LNK2028: Nicht aufgelöstes Token (0A000018) ""extern "C" int __stdcall WSAStartup(unsigned short,struct WSAData *)" (?WSAStartup@@$$J18YGHGPAUWSAData@@@Z)", auf das in Funktion ""int __cdecl startWinsock(void)" (?startWinsock@@$$FYAHXZ)" verwiesen wird.
13
1>socket.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""extern "C" int __stdcall WSAStartup(unsigned short,struct WSAData *)" (?WSAStartup@@$$J18YGHGPAUWSAData@@@Z)" in Funktion ""int __cdecl startWinsock(void)" (?startWinsock@@$$FYAHXZ)".
14
1>C:\entwicklung\bot\host\winsock_console\Debug\winsock_console.exe : fatal error LNK1120: 2 nicht aufgelöste externe Verweise.


Klar kann man nun sagen, es steht doch alles da. Mir ist bewusst, dass 
er beim linken das Symbol "WSAStartup" nicht finden kann. Jedoch weiß 
ich einfach nicht mehr weiter. Die lib "ws2_32.lib" habe ich bereits 
eingebunden (was laut google getan werden muss). Wäre dankbar für einen 
Tipp.

von bluppdidupp (Gast)


Lesenswert?

Der Fehler deutet aber schon daraufhin, dass die .lib nicht richtig 
eingebunden ist bzw. er sie nicht einbinden will.
Beim MS-Compiler reicht auch:
#pragma comment(lib, "ws2_32.lib")
direkt im Quelltext (z.B. über deinen include-Zeilen)

von brechbunkt (Gast)


Angehängte Dateien:

Lesenswert?

Herzlichen Dank. Mit der Zeile funktioniert es.

Aber um zu verstehen was ich falsch gemacht habe würde ich den Fall 
gerne noch ein wenig "offen" lassen.
Im screenshot ist zu sehen, wie und wo ich die lib eingebunden habe. 
Wäre das zumindest richtig gewesen?

von Peter II (Gast)


Lesenswert?

brechbunkt schrieb:
> Im screenshot ist zu sehen, wie und wo ich die lib eingebunden habe.
> Wäre das zumindest richtig gewesen?

du hast nur ein Verzeichnis eingebunden, wo nach einer lib gesucht wird, 
aber nicht die lib selber eingebunden.

Ich glaube das geht bei linker -> eingabe

Der Verzeichnis braucht man eigentlich nicht, bei den System libs.

von Timmo H. (masterfx)


Lesenswert?

Was du damit gemacht hast, ist einen Suchpfad für die Libs zu ergänzen. 
Der Pfad alleine bindet noch nicht die Lib ein, sondern sagt dem 
Compiler nur wenn ein "#pragma comment(lib..." dann guck auch in dem 
Verzeichnis nach der lib. Bei Standard-Libs (wie eben z.B. die ws2_32) 
brauchst du i.d.R. aber keinen zusätzlichen Pfad hinzufügen

EDIT: zu langsam

: Bearbeitet durch User
von Freddy Frettchen (Gast)


Lesenswert?

> wenn ein "#pragma comment(lib..." dann guck auch in dem
> Verzeichnis nach der lib.

Nicht nur bei Pragma, auch bei Librarys, die "normal" unter "zusätzliche 
Abhängigkeiten" ohne Pfad eingegeben werden.

Das ist übrigens bei fast allen Entwicklungsumgebungen so (damit man 
eben bei zusammengehörigen Bibliotheken nicht immer wieder den Pfad 
angeben muss).
Es gibt auch Leute, die - um sich Pfadangaben komplett zu sparen - 
einfach alles in den Haupt-SDK-Pfad kopieren, was eine eher schlechte 
Idee ist. Die einzigen Ausnahmen sind meiner Meinung nach zusätzliche 
OpenGL-Header und -Libs - z.B. FreeGLUT - in den jeweiligen 
Standard-GL-Include- und Lib-Unterverzeichnissen.

von brechbunkt (Gast)


Lesenswert?

Leider muss ich den thread noch mal neu aufleben lassen. Die Tipps mit 
dem library einbinden haben ja super funktioniert. Obwohl sie nun 
bereits eingebunden ist, erscheint der gleiche Fehler schon wieder und 
der Linker Vermisst das Symbol für den Befehl "inet_addr()".


1
/* avoid conflicts by including windows.h before winsock2.h */
2
#ifndef WIN32_LEAN_AND_MEAN
3
#define WIN32_LEAN_AND_MEAN
4
#endif
5
6
7
/*___ includes _______________________________________________________________*/
8
9
#include <windows.h>
10
#include <stdio.h>
11
#include <winsock2.h>
12
13
#include "stdafx.h"
14
//#include "socket.h"
15
16
#pragma comment(lib, "ws2_32.lib")
17
18
using namespace System;
19
20
21
/*___ defines ________________________________________________________________*/
22
/* use Winsock version number 1.2 */
23
#define WIN_SOCK_VER_MAJOR                      1
24
#define WIN_SOCK_VER_MINOR                      2
25
26
/* AF_INET = TCP/IP */
27
#define SOCK_ADDR_FAMILY                        AF_INET
28
29
/* SOCK_STREAM = TCP Socket */
30
#define SOCK_TYPE                               SOCK_STREAM
31
32
/* normaly use 0 */
33
#define SOCK_PROTOCOL                           0
34
35
36
/*___ enumerations ___________________________________________________________*/
37
38
/*___ function prototypes ____________________________________________________*/
39
40
/*___ variables ______________________________________________________________*/
41
42
/*___ functions ______________________________________________________________*/
43
44
/* start socket */
45
int startWinsock(void)
46
{
47
    WSADATA wsa;
48
    return WSAStartup(MAKEWORD(2,0),&wsa);
49
}
50
51
52
int main(array<System::String ^> ^args)
53
{
54
    WORD WinsockVer = MAKEWORD(WIN_SOCK_VER_MAJOR,WIN_SOCK_VER_MINOR);
55
56
    Console::Title = "winsock joystick connection";     /* set title of window */
57
    Console::WriteLine(L"here is winsock_console");
58
59
60
    /* ___ start a socket ______________________________ */
61
    long rc;
62
    rc = startWinsock();
63
64
    if(rc!=0)
65
    {
66
        printf("Fehler: startWinsock, fehler code: %d\n",rc);
67
        return 1;
68
    }
69
    else
70
    {
71
        printf("Winsock gestartet!\n");
72
    }
73
74
75
    /* ___ create a socket client ______________________________ */
76
    SOCKET sock;
77
    sock = socket(SOCK_ADDR_FAMILY, SOCK_TYPE, SOCK_PROTOCOL);
78
79
    if( sock == INVALID_SOCKET)
80
    {
81
        printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n", WSAGetLastError());
82
        return 1;
83
    }
84
    else
85
    {
86
        printf("Socket erstellt!\n");
87
    }
88
89
    
90
    /* ___ connect to server ______________________________ */
91
    unsigned long inet_addr(char* cp );
92
    SOCKADDR_IN addr;
93
94
    memset(&addr, 0, sizeof(SOCKADDR_IN));  // zuerst alles auf 0 setzten 
95
    addr.sin_family = SOCK_ADDR_FAMILY;
96
    addr.sin_port = htons(12345);           // wir verwenden mal port 12345
97
    addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // zielrechner ist unser eigener
98
99
100
    rc=connect(sock,(SOCKADDR*)&addr,sizeof(SOCKADDR));
101
    if(rc==SOCKET_ERROR)
102
    {
103
        printf("Fehler: connect gescheitert, fehler code: %d\n",WSAGetLastError());
104
        return 1;
105
    }
106
    else
107
    {
108
        printf("Verbunden mit 127.0.0.1..\n");
109
    }
110
111
    return 0;
112
}
1
1>winsock_console.obj : error LNK2028: Nicht aufgelöstes Token (0A000005) ""unsigned long __cdecl inet_addr(char *)" (?inet_addr@@$$FYAKPAD@Z)", auf das in Funktion ""int __clrcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP$01AP$AAVString@System@@@Z)" verwiesen wird.
2
1>winsock_console.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""unsigned long __cdecl inet_addr(char *)" (?inet_addr@@$$FYAKPAD@Z)" in Funktion ""int __clrcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP$01AP$AAVString@System@@@Z)".

von brechbunkt (Gast)


Lesenswert?

Ich sollte vielleicht noch kurz erwähnen, dass sich die Fehlermeldung 
rein auf die Zeile:
1
addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // zielrechner ist unser eigener
bezieht. Um den Zusammenhang zu gewähren, habe ich aber mal den gesamten 
Code dargestellt.

von brechbunkt (Gast)


Lesenswert?

Auf dieser Seite...

http://msdn.microsoft.com/de-de/library/windows/desktop/ms738557%28v=vs.85%29.aspx

...sehe ich gerade, ich würde noch eine Ws2_32.dll benötigen? Müsste ich 
diese nun noch irgendwie im VisualStudio einbinden?

von Mikrokotroller (Gast)


Lesenswert?

brechbunkt schrieb:
> ...sehe ich gerade, ich würde noch eine Ws2_32.dll benötigen? Müsste ich
> diese nun noch irgendwie im VisualStudio einbinden?

Nein, die befindet sich im Windows-Verzeichnis. Du linkst die 
Systembibliotheken ja dynamisch, nicht statisch. D.h., in der *.lib 
befinden sich (in diesem Fall) nicht die Funktionen selbst, sondern nur 
Verweise auf die jeweilige Windows-DLL. Diese wird dann beim 
Programmstart automatisch gefunden und geladen. BTW: #include "stdafx.h" 
immer nach oben.

von Mikrokotroller (Gast)


Lesenswert?

Gibt es eigentlich einen Grund dafür, dass du C++/CLI verwendest? 
Abgesehen von der "Vermittlung" zwischen .NET-Anwendungen und nativen 
Bibliotheken ist das eigentlich kaum gebräuchlich. Ich würde eher 
"richtiges" C++ benutzen. Oder war das ein Versehen (falschen Projekttyp 
gewählt)?

von brechbunkt (Gast)


Lesenswert?

Mikrokotroller schrieb:
> BTW: #include "stdafx.h" immer nach oben.

Hab's nun in die erste Zeile verschoben


Mikrokotroller schrieb:
> Gibt es eigentlich einen Grund dafür, dass du C++/CLI verwendest?

Nein, War nur meine Unwissenheit. Da CLI für "Command Line" steht, 
dachte ich, dass ich das wählen müsste.

Habe den Code nun in einer neuen Win32-Konsolenanwendung eingefügt. An 
der Fehlermeldung wegen der Funktion "inet_addr()" hat sich natürlich 
(leider) nichts geändert.

von Mikrokotroller (Gast)


Lesenswert?

brechbunkt schrieb:
> Habe den Code nun in einer neuen Win32-Konsolenanwendung eingefügt. An
> der Fehlermeldung wegen der Funktion "inet_addr()" hat sich natürlich
> (leider) nichts geändert.

Das hatte ich auch nicht angenommen. Es kann dich aber evtl. vor anderen 
Irritationen bewahren.

Nun lösche bitte die Zeile

unsigned long inet_addr(char* cp);

von brechbunkt (Gast)


Lesenswert?

Ich dreh durch...  Das war es.

Eigentlich wäre diese Zeile eine Funktionsdeklaration. Kann dann 
natürlich nicht gehen. Schade, dass die Fehlermeldung mich nicht auf 
diese Zeile "gelenkt" hat. Da ich den Code (falsch) in mein Projekt 
kopiert habe, bin ich davon ausgegangen, dass der garantiert keinen 
Fehler haben wird.

Ein Riesen Danke schön für die Unterstützung.
Bin echt froh, dass es dieses Forum gibt. Ich hätte wohl eher das Visual 
Studio neu installiert, als an dieser Stelle meinen Fehler zu suchen 
(schließlich sind ja immer die anderen Schuld ;) )

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.