JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=576252f81ac1999b085203abf001457aMedaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

c++ netzwerkprogrammierung dateiübertragung
Gehe zu Seite Zurück  1, 2
 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung
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

BeitragVerfasst am: 15.09.2008, 18:10    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
newby
JLI'ler



Anmeldedatum: 17.08.2007
Beiträge: 106

Medaillen: Keine

BeitragVerfasst am: 16.09.2008, 15:16    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
David
Super JLI'ler


Alter: 39
Anmeldedatum: 13.10.2005
Beiträge: 315

Medaillen: Keine

BeitragVerfasst am: 16.09.2008, 19:48    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
newby
JLI'ler



Anmeldedatum: 17.08.2007
Beiträge: 106

Medaillen: Keine

BeitragVerfasst am: 17.09.2008, 13:30    Titel: Antworten mit Zitat

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)&parameter, 0, &ThreadId);
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
David
Super JLI'ler


Alter: 39
Anmeldedatum: 13.10.2005
Beiträge: 315

Medaillen: Keine

BeitragVerfasst am: 17.09.2008, 15:57    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
newby
JLI'ler



Anmeldedatum: 17.08.2007
Beiträge: 106

Medaillen: Keine

BeitragVerfasst am: 17.09.2008, 19:45    Titel: Antworten mit Zitat

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 Question
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
David
Super JLI'ler


Alter: 39
Anmeldedatum: 13.10.2005
Beiträge: 315

Medaillen: Keine

BeitragVerfasst am: 17.09.2008, 20:30    Titel: Antworten mit Zitat

Keine Ahnung. Ich weiß nicht wie t_Send bei dir deklariert ist.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
newby
JLI'ler



Anmeldedatum: 17.08.2007
Beiträge: 106

Medaillen: Keine

BeitragVerfasst am: 18.09.2008, 13:37    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
David
Super JLI'ler


Alter: 39
Anmeldedatum: 13.10.2005
Beiträge: 315

Medaillen: Keine

BeitragVerfasst am: 18.09.2008, 14:22    Titel: Antworten mit Zitat

Mach ne normale Funktion draus (keine Methode einer Klasse), oder eine statische Methode.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Deviloper
Junior JLI'ler



Anmeldedatum: 31.05.2006
Beiträge: 77

Medaillen: Keine

BeitragVerfasst am: 18.09.2008, 15:57    Titel: Antworten mit Zitat

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 ... Wink CreateThread einfach this-Zeiger übergeben ...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
newby
JLI'ler



Anmeldedatum: 17.08.2007
Beiträge: 106

Medaillen: Keine

BeitragVerfasst am: 18.09.2008, 16:30    Titel: Antworten mit Zitat

versteh ich nicht mit dem this-zeiger, wenn ich die funktion aus der klasse raushole gehts auch nicht
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
David
Super JLI'ler


Alter: 39
Anmeldedatum: 13.10.2005
Beiträge: 315

Medaillen: Keine

BeitragVerfasst am: 18.09.2008, 16:51    Titel: Antworten mit Zitat

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 )&parameter, 0, &ThreadId );

}
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
newby
JLI'ler



Anmeldedatum: 17.08.2007
Beiträge: 106

Medaillen: Keine

BeitragVerfasst am: 18.09.2008, 19:45    Titel: Antworten mit Zitat

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, &parameter, 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
Benutzer-Profile anzeigen Private Nachricht senden
newby
JLI'ler



Anmeldedatum: 17.08.2007
Beiträge: 106

Medaillen: Keine

BeitragVerfasst am: 19.09.2008, 16:38    Titel: Antworten mit Zitat

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, &parameter, 0, &ThreadId);
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung Alle Zeiten sind GMT
Gehe zu Seite Zurück  1, 2
Seite 2 von 2

 
Gehe zu:  
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

Impressum