PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ich will auch mal ... socketprogrammierung ...



TheDodger
18-08-2001, 18:45
So, damit nicht immer andere zum Thema Socketprogrammierung schreiben, will ich mich auch einmal damit beschäftigen ... ;)

ich habe mir das tuturial von http://home.t-online.de/home/felix.opatz/socket-tipps.html
zu gemüte geführt und einiges davon auch ausprobiert ...

bei einem allerdings scheitere ich kläglich ... :(

Hier mal ein stück 'relevanter' code:


struct sockaddr_in _server;
struct sockaddr_in cli;

_socket = socket( AF_INET, SOCK_STREAM, 0 );

if( _socket == -1 )
{
perror( "socket() failed" );
return 2;
}

_server.sin_addr.s_addr = INADDR_ANY;
_server.sin_port = htons( ( unsigned short int ) conf->getServerPort( ) );
_server.sin_family = AF_INET;

if( bind( _socket, (struct sockaddr*)&_server, sizeof( _server ) ) == -1 )
{
perror("bind() failed");
return 3;
}

if( listen( _socket, 3 ) == -1 )
{
perror( "listen() failed" );
return 4;
}

for( ;; )
{
cli_size = sizeof( cli );
c = accept( _socket, &cli, &cli_size );


lasse ich die zeile


c = accept( _socket, &cli, &cli_size );

so wie sie ist, meckert mein gcc und meint:


server.cpp: In method `bool server::run()':
server.cpp:108: type `sockaddr' is not a base type for type `sockaddr_in'


ändere ich das wie im tuturial in :



c = accept( _socket, (struct sockaddr *)&cli, &cli_size );


um, meint der compiler:



server.cpp: In method `bool server::run()':
server.cpp:107: passing `int *' as argument 3 of `accept(int, sockaddr *, socklen_t *)' changes signedness


und daraus werd ich nun nicht mehr schlau ...

was mach ich denn nun falsch?

ich hoffe, ihr könnt mir helfen! ;)

B.

thommy
20-08-2001, 08:20
Unter Linux muss cli_size vom Typ socklen_t sein, unter Windows ist es ein int.

Unter C++ ist es guter Stil, anstatt dem C-like Casts static_cast, dynamic_cast... zu verwenden (nur als Tipp).

Thomas

TheDodger
20-08-2001, 12:18
<BLOCKQUOTE><font size="1" face="Arial,Helvetica,Geneva">Zitat:</font><HR>Original erstellt von thommy:
<STRONG>Unter Linux muss cli_size vom Typ socklen_t sein, unter Windows ist es ein int.
</STRONG>
[/quote]
ja, das hatte ich heut morgen auch so gesehen ... :-/

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,Geneva">Zitat:</font><HR>
<STRONG>
Unter C++ ist es guter Stil, anstatt dem C-like Casts static_cast, dynamic_cast... zu verwenden (nur als Tipp).
</STRONG>[/quote]

kannst du mir das mal bitte kurz erklären?

B.

thommy
20-08-2001, 12:52
Anstatt

c = accept( _socket, (struct sockaddr *)&cli, &cli_size );

schreibt man in C++ bspw:

c = accept( _socket, reinterpret_cast&lt;struct sockaddr*&gt;(&cli), &cli_size);

Durch letztere Vorgehensweise wird der Compiler trotz eines Casts eine Typprüfung vornehmen. Das Beispiel ist allerdings schlecht gewählt, da reinterpret_cast so ziemlich das gefährlichste Konstrukt des Castens ist. Hier ist diese Art allerdings notwendig.

Im Netz findest Du zahlreiche Seiten, die den Sinn besser verdeutlichen, als ich es auf die Schnelle könnte. Bspw. hier: http://www.ictp.trieste.it/~manuals/programming/sun/c-plusplus/c++_ug/Cast.new.doc.html

Thomas

TheDodger
22-08-2001, 04:01
Danke!
guten Link, hat mir das Thema doch wirklcih schon näher gebracht ... :)

B.

RoRoe
04-09-2001, 20:42
&gt;server.cpp: In method `bool server::run()':server.cpp:107: passing `int *' as argument 3 of `accept(int, sockaddr *, socklen_t *)' changes signedness

Das Problem des Compilers ist das Format des 3 Arguments!
Wenn es vom Typ unsigned int ist müßte es funktionieren.

Also:
u_int cli_size;

...
cli_size = sizeof(sockaddr);
c = accept( _socket, &cli, &cli_size );
...