Thread &nd nicht Statistische funktionen

07/20/2013 11:27 [uLow]NTX?!#1
hey,

Vorweg: ich bin (so würde ich es mal sagen) erst ein Anfänger in sachen C++, also nicht gleich rummeckern weil code XY nicht gut aussieht . Verbesserungsvorschlage sidn jedoch gerne gesehen! :D


Also ich habe mit Winsock 2 einen Klasse erstellt mit der ich auch zu einem TCP Server verbinden kann und auch senden kann, soweit ist das kein problem.
Ich möchte nun natürlich auch daten empfangen können und brauche eine recv() funktion.

ich hatte mir gedacht diese Funktion in einem neuen Thread laufen zulassen, da die recv() funktion solange blockt, bis etwas neues reinkommt.
Nur kann ich aus diesem Thread nicht auf den SOCKET zugreifen, weil er nicht static ist und das ist mein problem..

Wie kann ich dieses Problem lösen?

Hier auchnoch die klasse:

PHP Code:
//---------------------------------------------------------------------------
#pragma comment( lib, "ws2_32.lib" )
#include "Unit1.h"
#include <Winsock2.h>
#include <windows.h>
//---------------------------------------------------------------------------

class SocketInstance{
        private:
            
bool connected;
            
SOCKET s;
             
SOCKET staticS;
            
SOCKADDR_IN addr;
            
long rc;
            
HANDLE hThread;

             static 
DWORD recvData(){
                while(
true ){

                        
char buf[1024];
                        
//recv(s,buf,sizeof(buf),0);
                            /*if (rc == SOCKET_ERROR) {
                                Form1->Memo1->Lines->Add("Connection to server lost");
                                 break;
                            } */
                    
Sleep(10);
                }
            }
        public:
            
bool createSocket(charip,charport){

                
connected false;
                
WSADATA wsa;
                
rc WSAStartup(MAKEWORD(2,0),&wsa);
                if (
rc == 0) {
                   
socket(AF_INET,SOCK_STREAM,0);
                   
SocketInstance::staticS s;
                    if (
== INVALID_SOCKET){
                        
disconnect();
                    }else{
                       
memset(&addr,0,sizeof(SOCKADDR_IN));
                        
addr.sin_family=AF_INET;
                        
addr.sin_port htonsatoiport ) );

                        
addr.sin_addr.s_addr=inet_addrip );

                        
rc connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR));

                        if (
rc == SOCKET_ERROR){
                            
disconnect();
                            return 
false;
                        }
                        else {
                            
connected true;
                            
hThread CreateThread(NULL0, (LPTHREAD_START_ROUTINE)recvData NULL0NULL);

                            return 
true;
                        }
                    }
                }

                return 
false;
            }

             
int sendToServer(charbuf){
                    
send(s,buf,strlen(buf),0);
                     if ( 
WSAGetLastError() == 0  ) {
                         return 
1;
                     } else{
                         return 
0;
                     }

             }

             
void disconnect(){
                
TerminateThread(hThread,0);
                
connected false;
                
closesocket(s);
                
WSACleanup();

             }

             
void getLastError(){
                
ShowMessage(  WSAGetLastError() );
             }


}; 

Ich sage schonmal im vorwege Danke für eure Hilfe.
07/20/2013 11:51 Schlüsselbein#2
Code:
#include <iostream>
#include <thread>

struct foo
{
	void bar()
	{
		std::cout << std::this_thread::get_id() << std::endl;
	}

	void start()
	{
		std::thread t(&foo::bar, this);
		std::cout << std::this_thread::get_id() << std::endl;
		t.join(); // bzw t.detach()
	}
};

int main()
{
	foo f;
	f.start();
}
Dein Code ist mehr C, als C++. Benutz C++ wenn dann schon mit allen Features und denke mal darüber nach, eine fertige Netzwerklib zu benutzen.
07/20/2013 12:18 [uLow]NTX?!#3
Quote:
Originally Posted by Schlüsselbein View Post
Code:
#include <iostream>
#include <thread>

struct foo
{
	void bar()
	{
		std::cout << std::this_thread::get_id() << std::endl;
	}

	void start()
	{
		std::thread t(&foo::bar, this);
		std::cout << std::this_thread::get_id() << std::endl;
		t.join(); // bzw t.detach()
	}
};

int main()
{
	foo f;
	f.start();
}
Dein Code ist mehr C, als C++. Benutz C++ wenn dann schon mit allen Features und denke mal darüber nach, eine fertige Netzwerklib zu benutzen.
Könntest du mir einen lib empfehlen?

Und sieht mein Struktur von dem Code so ok aus?
07/20/2013 13:33 Schlüsselbein#4
Was hast du vor? Je nach Problemstellung kann man Libs empfehlen.
Der Code ist so ganz okay - gibt hier in jedem zweiten Thread schlimmeres.
07/20/2013 13:38 [uLow]NTX?!#5
Quote:
Originally Posted by Schlüsselbein View Post
Was hast du vor? Je nach Problemstellung kann man Libs empfehlen.
Der Code ist so ganz okay - gibt hier in jedem zweiten Thread schlimmeres.
Aso okay ;D

Ich habe vor in richtung Clientless mit einer GUI zu arbeiten.
07/25/2013 13:40 Tyrar#6
Um ehrlich zu antworten: der Code ist Schrott.

1. Du initialisierst die WinSock API bei jeder Verbindung komplett neu.
2. Du übergibst selbst den Port als char array.
3. Warum überhaupt char arrays und nicht die schöne std::string Klasse?
4. Ein statischer Inputbuffer, wo man die eigentliche größe der Daten auslesen könnte.
5. Beim senden der Daten mit strlen zu arbeiten ist in den meisten Fällen auch nicht sehr ratsam. Besonders wenn es auch binäre Daten sind, die gesendet werden sollen.
6. Warum überhaupt so viel C wenn dir doch die Möglichkeiten von C++ zur verfügung stehen?
(7.) Ist der Stil unschön.

Zur Frage selbst: ich habe mir für meinen Clientless eine thread Klasse geschrieben, die eine pure virtual funktion namens "run" besitzt und eine statische member funktion namens "__run", welche für die Threadstart Funktionen verwendet wird. Meine Klassen erben von der Thread-Klasse und implementieren die Funktion "run()", welche dann die nicht statische Memberfunktion ist.
07/25/2013 18:39 [uLow]NTX?!#7
Hätte erlich nicht gedacht, dass einer von euch beiden auf den Thread Antworten wird.

Naja meine antworten sind rot
Quote:
Originally Posted by HeavyHacker View Post
Um ehrlich zu antworten: der Code ist Schrott. Deswegen erwähnte ich, dass ich ein Anfänger bin ;)

1. Du initialisierst die WinSock API bei jeder Verbindung komplett neu.
2. Du übergibst selbst den Port als char array. 1&2 -> Jup, hat den Grund das ich das als KLasse machen wollte, welche ich nicht nur für dieses "Projekt" nutzen will, deswegen auch Port & IP
3. Warum überhaupt char arrays und nicht die schöne std::string Klasse?
4. Ein statischer Inputbuffer, wo man die eigentliche größe der Daten auslesen könnte.
5. Beim senden der Daten mit strlen zu arbeiten ist in den meisten Fällen auch nicht sehr ratsam. Besonders wenn es auch binäre Daten sind, die gesendet werden sollen.Ist doch ein verbesserungsvorschlag -> Siehe Vorwort 1st Post ;) Danke
6. Warum überhaupt so viel C wenn dir doch die Möglichkeiten von C++ zur verfügung stehen?[COLOR="Red"]Um erlich zusein, weil ich den genauen unterschied zwischen C & c++ vorher noch nicht kannte und ich mich erst nahc dem Post von Schlüsselbein mit den genauen Unterschied auseinandergesetzt habe /COLOR]
(7.) Ist der Stil unschön.

Zur Frage selbst: ich habe mir für meinen Clientless eine thread Klasse geschrieben, die eine pure virtual funktion namens "run" besitzt und eine statische member funktion namens "__run", welche für die Threadstart Funktionen verwendet wird. Meine Klassen erben von der Thread-Klasse und implementieren die Funktion "run()", welche dann die nicht statische Memberfunktion ist. Joar ich will den Char bisher nur Ingame sehen und evtl später mal sehen ob ich weitermache
Btw. Ich habe eine lösung gefunden mit der ich erstmal zufrieden bin, ich werde die zwar sicher noch überarbieten aber das hat erstmal zeit.

v.d #clsreq
07/25/2013 19:38 Tyrar#8
Was ich mit Punkt 1 sagen wollte: es wäre intelligenter, die Winsock API nur einmal ganz am Anfang des Programms zu initialisieren.
Mit Punkt 2: warum übergibst du nicht einfach direkt einen short integer?

Außerdem als Anfänger direkt so ein Projekt... Meeehhh...
07/26/2013 16:56 _Roman_#9
Mag ja sein, dass man als Anfänger nicht die komplette Ahnung für so ein Projekt hat, aber learning by doing sag ich nur. So lernt man am besten
07/26/2013 19:08 MrSm!th#10
Nein, so verbaut man sich am besten den Stil :/