|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 15.09.2008, 18:10 Titel: |
|
|
fkrauthan hat Folgendes geschrieben: | also wenn du die Standrad CSockets hernimmst bekommst du als Socket einfach einen int wert. Der ist -1 wenn der Socket ungültig ist. |
Das ist plattformabhängig.
Bei Windows/Linux ist es einmal int und einmal unsigned int, daher ist der Fehlerwert auch einmal 0 und einmal -1 (wierum es genau ist, weiß ich alelrdings nicht mehr).
Am besten arbeitet man mit typedefs und Konstanten, dann kann man sein Programm später leicht anpassen.
http://zotteljedi.de/
Finde ich eine sehr schöne Seite, es wird auch eigentlich überall auf die Plattformunterschiede eingegangen.
Allerdings würde ich auch zu boost::asio raten. Es ist einfach moderner und so die oben beschriebenen Probleme tauchen von Anfang an nicht auf. _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
newby JLI'ler
Anmeldedatum: 17.08.2007 Beiträge: 106
Medaillen: Keine
|
Verfasst am: 16.09.2008, 15:16 Titel: |
|
|
das die sich nicht mögen war nicht erst gemeint^^
mir ist schon klar das ich irgendwas falsch mache.
wie würdest du denn du denn einen thread erstellen, der aus einer funktion mit parametern besteht? ohne (LP_THREAD_STARTROUTINE) bekomme ich immer irgendwelche konvertierungsfehler. davon abgesehen habe ich die parameter zum test garnicht benutzt und kann deshalb ausschließen das es daran liegt.
@Jonathan_Klein: Ich guck mir das auf jeden fall nochmal an, aber eigentlich sind Winsockets schön einfach für mich (wenn ich mal von der Asynchronisation mit den threads absehe) |
|
Nach oben |
|
|
David Super JLI'ler
Alter: 39 Anmeldedatum: 13.10.2005 Beiträge: 315
Medaillen: Keine
|
Verfasst am: 16.09.2008, 19:48 Titel: |
|
|
newby hat Folgendes geschrieben: |
wie würdest du denn du denn einen thread erstellen, der aus einer funktion mit parametern besteht? ohne (LP_THREAD_STARTROUTINE) bekomme ich immer irgendwelche konvertierungsfehler. davon abgesehen habe ich die parameter zum test garnicht benutzt und kann deshalb ausschließen das es daran liegt. |
Du übergibst aber nicht die Adresse zur Funktion sondern den Rückgabewert, von Send, gecastet nach LPTHREAD_START_ROUTINE. Desweiteren ist es natürlich so, das du jede beliebige Funktion, zu einer "LPTHREAD_START_ROUTINE" casten kannst -- Es ist dennoch keine. Was CreateThread erwartet ist eine Funktion mit der Signatur
CPP: | DWORD WINAPI ThreadProc( LPVOID lpParameter ) |
und eigentlich solltest du nichts anderes übergeben. Falls dir der eine Parameter zu wenig ist, nimm halt eine Struktur, die alle Parameter hält, und übergib ein Objekt vom Typ der Struktur. LPVOID machts möglich.
Hier mal ein kleines Client/Server Beispiel:
Server
CPP: | #include <stdio.h>
#include <winsock2.h>
#include <windows.h>
#include <conio.h>
#pragma comment( lib, "Ws2_32.lib" )
#define PORT 54321
DWORD WINAPI ReceiverProc( LPVOID lpParameter )
{
char buffer[ 512 ];
SOCKET receiver = *( ( SOCKET* )lpParameter );
while ( true )
{
int ret = recv( receiver, buffer, 512, 0 );
if ( ret == SOCKET_ERROR || ret == 0 )
{
printf( "error ");
break;
}
buffer[ ret ] = 0;
printf( "received: %s\n", buffer );
}
return 0;
}
int main()
{
WSADATA wsaData;
if ( WSAStartup( MAKEWORD( 2, 2 ), &wsaData ) != 0 )
{
printf( "WSAStartup failed..." );
return 0;
}
SOCKET listener =
WSASocket( AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED );
if ( listener == INVALID_SOCKET )
{
printf( "WSASocket failed..." );
WSACleanup();
return 0;
}
sockaddr_in sinfo;
sinfo.sin_family = AF_INET;
sinfo.sin_addr.s_addr = inet_addr( "127.0.0.1" );
sinfo.sin_port = PORT;
if ( bind( listener, ( SOCKADDR* )&sinfo, sizeof( sinfo ) ) == SOCKET_ERROR )
{
printf( "binding socked failed..." );
closesocket( listener );
WSACleanup();
return 0;
}
if ( listen( listener, SOMAXCONN ) == SOCKET_ERROR )
{
printf( "listening error" );
closesocket( listener );
WSACleanup();
return 0;
}
HANDLE hThread = NULL;
SOCKET receiver = accept( listener, NULL, NULL );
if ( receiver != INVALID_SOCKET )
{
hThread =
CreateThread( NULL, 0, ReceiverProc, ( LPVOID )&receiver, 0, 0 );
}
closesocket( listener );
printf( "'X' druecken um Server herunterzufahren\n" );
int c = 0;
while ( c != 'X' )
{
c = _getch();
}
closesocket( receiver );
WaitForSingleObject( hThread, INFINITE );
WSACleanup();
printf( "bye bye" );
} |
Client
CPP: | #include <winsock2.h>
#include <stdio.h>
#pragma comment( lib, "Ws2_32.lib" )
#define PORT 54321
int main()
{
WSADATA wsaData;
if ( WSAStartup( MAKEWORD( 2, 2 ), &wsaData ) != 0 )
{
printf( "WSAStartup failed..." );
return 0;
}
SOCKET socket =
WSASocket( AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED );
sockaddr_in sinfo;
sinfo.sin_family = AF_INET;
sinfo.sin_addr.s_addr = inet_addr( "127.0.0.1" );
sinfo.sin_port = PORT;
if ( connect( socket, ( SOCKADDR* )&sinfo, sizeof( sinfo ) ) == SOCKET_ERROR )
{
printf( "connect failed" );
WSACleanup();
return 0;
}
char buffer[ 512 ] = { 0 };
while ( strcmp( buffer, "exit" ) )
{
gets_s( buffer, 512 );
send( socket, buffer, strlen( buffer ), 0 );
}
closesocket( socket );
WSACleanup();
} |
|
|
Nach oben |
|
|
newby JLI'ler
Anmeldedatum: 17.08.2007 Beiträge: 106
Medaillen: Keine
|
Verfasst am: 17.09.2008, 13:30 Titel: |
|
|
hey, danke für den post, aber wenn ich versuche eine in LPVOID gecastete struktur zu übergeben, oder überhaupt einen thread so zu erstellen, bekomme ich die fehlermeldung: "Dem Funtionsaufruf fehlt die Argumentlist"
CPP: | parameter.client = client;
strcpy(parameter.sendmessage, message);
DWORD ThreadId = 0;
HANDLE ThreadHandle = 0;
ThreadHandle = CreateThread(NULL, 0, t_Send, (LPVOID)¶meter, 0, &ThreadId);
|
|
|
Nach oben |
|
|
David Super JLI'ler
Alter: 39 Anmeldedatum: 13.10.2005 Beiträge: 315
Medaillen: Keine
|
Verfasst am: 17.09.2008, 15:57 Titel: |
|
|
Wieso liest du nicht einfach mal in der Dokumentation nach (oder wenigstens mein Beispiel hättest du lesen können...)?
msdn hat Folgendes geschrieben: |
HANDLE WINAPI CreateThread(
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in SIZE_T dwStackSize,
__in LPTHREAD_START_ROUTINE lpStartAddress,
__in_opt LPVOID lpParameter,
__in DWORD dwCreationFlags,
__out_opt LPDWORD lpThreadId
); |
Was sehen wir da? Der dritte Parameter ist der Callback (also deine Funktion), der 4. Parameter ist der Wert der als Parameter, beim Aufruf des Callbacks, übergeben wird. |
|
Nach oben |
|
|
newby JLI'ler
Anmeldedatum: 17.08.2007 Beiträge: 106
Medaillen: Keine
|
Verfasst am: 17.09.2008, 19:45 Titel: |
|
|
aber so mach ich das doch oder? mein drittes parameter ist die funktion, mein viertes das parameter der funktion oder? was mach ich denn falsch |
|
Nach oben |
|
|
David Super JLI'ler
Alter: 39 Anmeldedatum: 13.10.2005 Beiträge: 315
Medaillen: Keine
|
Verfasst am: 17.09.2008, 20:30 Titel: |
|
|
Keine Ahnung. Ich weiß nicht wie t_Send bei dir deklariert ist. |
|
Nach oben |
|
|
newby JLI'ler
Anmeldedatum: 17.08.2007 Beiträge: 106
Medaillen: Keine
|
Verfasst am: 18.09.2008, 13:37 Titel: |
|
|
in der klasseninitialisierung so:
CPP: | DWORD WINAPI t_Send(LPVOID parameter);
|
und in der initialisierung so:
CPP: | DWORD WINAPI CNetwork::t_Send(LPVOID parameter)
{
...
}
|
|
|
Nach oben |
|
|
David Super JLI'ler
Alter: 39 Anmeldedatum: 13.10.2005 Beiträge: 315
Medaillen: Keine
|
Verfasst am: 18.09.2008, 14:22 Titel: |
|
|
Mach ne normale Funktion draus (keine Methode einer Klasse), oder eine statische Methode. |
|
Nach oben |
|
|
Deviloper Junior JLI'ler
Anmeldedatum: 31.05.2006 Beiträge: 77
Medaillen: Keine
|
Verfasst am: 18.09.2008, 15:57 Titel: |
|
|
CPP: | class foo
{
static DWORD WINAPI _send(LPVOID ptr_this)
{ return static_cast<foo*>(ptr_this)->send(); }
protected:
virtual const DWORD send() { return S_OK; }
}; | ... so ... CreateThread einfach this-Zeiger übergeben ... |
|
Nach oben |
|
|
newby JLI'ler
Anmeldedatum: 17.08.2007 Beiträge: 106
Medaillen: Keine
|
Verfasst am: 18.09.2008, 16:30 Titel: |
|
|
versteh ich nicht mit dem this-zeiger, wenn ich die funktion aus der klasse raushole gehts auch nicht |
|
Nach oben |
|
|
David Super JLI'ler
Alter: 39 Anmeldedatum: 13.10.2005 Beiträge: 315
Medaillen: Keine
|
Verfasst am: 18.09.2008, 16:51 Titel: |
|
|
Doch, das geht:
CPP: | DWORD WINAPI t_Send( LPVOID parameter )
{
}
// ...
int main()
{
// ...
parameter.client = client;
strcpy( parameter.sendmessage, message );
DWORD ThreadId = 0;
HANDLE ThreadHandle = 0;
CreateThread( NULL, 0, &t_Send, ( LPVOID )¶meter, 0, &ThreadId ); |
} |
|
Nach oben |
|
|
newby JLI'ler
Anmeldedatum: 17.08.2007 Beiträge: 106
Medaillen: Keine
|
Verfasst am: 18.09.2008, 19:45 Titel: |
|
|
in klassen funktioniert das irgendwie nicht, ist aber nicht schlimm, hab nämlich alles jetzt ohne klasse in eine dll gepackt.
Das Problem:
CPP: | DWORD WINAPI t_Send(LPVOID parameter)
{
sParam test;
strcpy(test.sendmessage, (char*)*((sParam*)parameter)->sendmessage); //den ausdruck find ich geil^^
MessageBox(0, test.sendmessage, "test", MB_OK);
return 0;
}
|
CPP: | parameter.sendmessage = "test";
DWORD ThreadId = 0;
HANDLE ThreadHandle = 0;
ThreadHandle = CreateThread(NULL, 0, t_Send, ¶meter, 0, &ThreadId);
|
funktioniert alles, nur die eine zeile, in der ich per strcpy die char* kopieren möchte, verursacht einen laufzeitfehler. Die threads scheinen aber zu funktionieren. |
|
Nach oben |
|
|
newby JLI'ler
Anmeldedatum: 17.08.2007 Beiträge: 106
Medaillen: Keine
|
Verfasst am: 19.09.2008, 16:38 Titel: |
|
|
ok, die laufzeitfehler wurden durch die strcpy funktion erzeugt. Ich hab ein bischen was geändert, aber irgendwie werden die Parameter garnicht mehr übertragen:
CPP: | WORD WINAPI t_Send(LPVOID parameter)
{
sParam test;
test.client = ((sParam*)parameter)->client;
test.sendmessage = ((sParam*)parameter)->sendmessage;
...
}
sParam parameter;
parameter.client = 1;
parameter.sendmessage = "test";
DWORD ThreadId = 0;
HANDLE ThreadHandle = 0;
ThreadHandle = CreateThread(NULL, 0, t_Send, ¶meter, 0, &ThreadId);
|
|
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
Powered by phpBB © 2001, 2005 phpBB Group Deutsche Übersetzung von phpBB.de
|