Winsock Problem



  • Hi,

    Ich habe einen Client und Server geschrieben.
    Der Server ist im listen Modus und fängt Clienten über den Port 12128 ab und speichert die verbundenen sockets ab um nach weiteren Clienten zu lauschen.

    Soo jetzt zum Problem:
    Der Server soll 2 ports haben. Einmal 12128 für den listen modus und einmal 13138 für verbundene Clienten.
    Dass heißt, wenn accept jetzt einen verbundenen socket rauswirft, soll dieser socket nicht mehr über port 12128 laufen, sondern über port 13138!
    wie kann ich das realisieren??
    Ich muss ja irgendwie den socket editieren oder?

    Edit:/
    Ich habs jetzt soo versucht:

    int connectedsocket(SOCKADDR_IN a)
    {
        SOCKET clientSocket = socket(AF_INET, SOCK_STREAM , 0);
    
    	if(clientSocket == INVALID_SOCKET)
    	{
    		AddText("Client-Fehler: Socket konnte nicht erstellt werden!"); 
    		return 1;
    	}
    	else
    	{
    		AddText("Client-Socket erstellt!"); 
    	}
    
    	addr2.sin_family = AF_INET;
    	addr2.sin_port = htons(13138);
    	addr2.sin_addr = a.sin_addr;
    
    	test = bind(clientSocket, (SOCKADDR*)&addr2, sizeof(SOCKADDR_IN));
    	if(test == SOCKET_ERROR)
    	{
    		AddText("Client-Fehler: Bind nicht möglich");
    		FehlerCode();
    		return 1;
    	}
    	else
    	{
    		AddText("Client-Socket an Port 13138 gebunden!");
    	}
    }
    

    Aber das klappt nur local, also 127.0.0.1 im Internet kommt der FehlerCode 6, also:

    Specified event object handle is invalid.An application attempts to use an event object, but the specified handle is not valid. Note that this error is returned by the operating system, so the error number may change in future releases of Windows.

    Aber was heißt das jetzt??
    Firewall ist aus Ports sind offen ...



  • ?!

    1. Server lauscht auf irgendneIP, Port 12128
    2. Client (sagen wir mal IP 123.12.12.12, Port 5000) verbindet sich nun mit dem Server
    3. Server nimmt die Verbindung an und gibt dir nen Socket zurück.

    Wo willst du da jetzt nen Port umbiegen?

    bzw: Was genau soll connectedsocket() da tun?
    Du erzeugst da einen neuen unverbundenen TCP-Socket und willst den auf irgendne IP (was ist das für ne IP?) mit Port 13138 binden?



  • Ich habe da der funktion die SOCKADDR_IN structur übergeben die accept ausgefüllt hat^^
    Dementsprechend sollte da dann auch die ip von dem clienten drin sein^^
    Ach ja und der SOCKET da ist global^^ .... hab mich vertippt...



  • RebornX schrieb:

    Der Server soll 2 ports haben. Einmal 12128 für den listen modus und einmal 13138 für verbundene Clienten.
    Dass heißt, wenn accept jetzt einen verbundenen socket rauswirft, soll dieser socket nicht mehr über port 12128 laufen, sondern über port 13138!

    wenn du das unbedingt so haben willst (warum auch immer), dann sollte der server sofort nach erfolgreicher verbindung den client-socket killen und auf dem zweiten listen-socket nur verbindungen von dem vorherigen client akzeptieren. der client muss dann den 'rausschmiss' erkennen und eine verbindung zu dem anderen port aufbauen.
    🙂



  • Darf ich fragen wozu das gut sein soll?

    bind() kann nur auf ungebindeten Sockets aufgerufen werden.
    Du kannst also auf bereits verbundenen Sockets (wie das was du von accept() bekommst) kein bind() aufrufen.

    Zudem kannst du bei einer bestehenden Verbindung nicht einfach den Port ändern.



  • ok hat sich erledigt ^^ .... Habe jetzt ne andere Möglichkeit gefunden die auch ganz gut funktioniert:
    Sobald ein Client sich mit dem listen port verbunden hat schickt der server eine nachrticht dem clienten das er abjetzt zum "connection port" connecten soll.



  • Edit: war wohl Unsinn



  • Nanyuki schrieb:

    Edit: war wohl Unsinn

    Wieso unsinn??
    Wenn große Mengen Daten übertragen werden, ist der port ja blockiert und kann solange nicht nach weiteren connections lauschen^^
    Deswegen will ich die communication zwischen client + server über einen extra port machen ^^.



  • Ich hab zwar k.A. was geschrieben wurde, aber:

    accept() kann direkt hintereinander weg etliche Verbindungen die über den selben Port reinkommen annehmen.
    Es ist nicht so das man nur jeweils eine Verbindung pro Server-Port haben kann sollte die Vorstellung hier jemand haben 😉
    Mit einem Apache-Webserver z.B. können auch etliche Browser gleichzeitig über denselben Server-Port kommunizieren.

    Daher ist mir auch nicht ganz klar, warum du unbedingt noch nen zweiten Port aufmachst und den Client anschließend mit dem verbinden lässt...



  • ähm ich weiiss nicht, aber da wird das ganze auch mit threads realisiert, so viel ich weiss. Ausserdem kann man via accept(); auf einen anderen Socket verweisen.
    Ungefähr so:

    connectSocket = accept(listenSocket, NULL, NULL);
    

    wobei connectedSocket und listenSocket zwei verschiedene Sockets sind. listenSocket i´st im listen Modus. und wenn er einen clienten hat, stellt er via accept eine verbindung mit connectSocket und dem Clienten her.
    So hab ich das auf jedenfall verstanden.
    hier noch der Code aus dem Tutorial:

    #include <windows.h>
    #include <winsock2.h>
    #include <iostream.h>
    
    using namespace std;
    
    int startWinsock()
    {
        WSADATA wsa;
        return WSAStartup(MAKEWORD(2,0),&wsa);
    }
    
    int main()
    {
        long rc;
        SOCKET acceptSocket;
        SOCKET connectedSocket;
        SOCKADDR_IN addr;
        char input;
    
        rc = startWinsock();
    
        if(rc != 0)
        {
              cout<<"Fehler: startWinsock, fehler code: "<<rc<<"\n";
              WSACleanup();
              return 1;
        }
        else
        {
            cout<<"Winsock gestartet!\n";
        }
    
        acceptSocket = socket(AF_INET,SOCK_STREAM,0);
    
        if(acceptSocket == INVALID_SOCKET)
        {
                        cout<<"Fehler: Der Socket konnte nicht erstellt werden, fehler code: "<<WSAGetLastError()<<"\n";
                        closesocket(acceptSocket);
                        WSACleanup();
                        return 1;
        }
        else
        {
            cout<<"Socket erstellt!\n";
        }
    
        memset(&addr,0,sizeof(SOCKADDR_IN));
        addr.sin_family=AF_INET;
        addr.sin_port=htons(12345);
        addr.sin_addr.s_addr=ADDR_ANY;
    
        rc = bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));
    
        if(rc == SOCKET_ERROR)
        {
                            cout<<"Fehler: bind, fehler code: "<<WSAGetLastError()<<"\n";
                            closesocket(acceptSocket);
                            WSACleanup();
                            return 1;
        }
        else
        {
            cout<<"Socket an port 12345 gebunden\n";
        }
    
        rc = listen(acceptSocket,10);
    
        if(rc == SOCKET_ERROR)
        {
                            cout<<"Fehler: listen, fehler code: "<<WSAGetLastError()<<"\n";
                            closesocket(acceptSocket);
                            closesocket(connectedSocket);
                            WSACleanup();
                            return 1;
        }
        else
        {
            cout<<"acceptSocket ist im listen Modus....\n";
        }
    
        connectedSocket = accept(acceptSocket,NULL,NULL);
    
        if(connectedSocket == INVALID_SOCKET)
        {
                                           cout<<"Fehler: accept, fehler code: "<<WSAGetLastError()<<"\n";
                                           closesocket(acceptSocket);
                                           closesocket(connectedSocket);
                                           WSACleanup();
                                           return 1;
        }
        else
        {
            cout<<"Neue Verbindung wurde akzeptiert!\n";
    
        }
    
        closesocket(acceptSocket);
        closesocket(connectedSocket);
        WSACleanup();
        cout<<"Beenden";
        cin>>input;
        return 0;
    }
    

    vielleicht konnte ich helfen.



  • also so gruselig wie sich das angehört hat, denkt rebornX das accept "nur" die daten des client ausliesst und auch über den "port" des "accept" mit dem server kommuniziert ... distanzier dich mal von der vorstellung socket == port wenn dein client connect zu deinem "accept" aufruft, stellt accept automatisch eine socket-verbindung her ... sockets sind hier sowas wie die die 2 enden eines kabel ... die verbindung bekommst du im result von accept zurück ... ist diese gültig, legst du sie dir in irgendeinem speicher ab und schickst accept in die neue runde ... natürlich musst du vorher dafür sorgen das dein connectedsocket (das wo das accept() result landet) wieder vernünftig initialisert wird.

    by the way ohne quellcode isses eh nur ein kristallkugelraten .... zeig doch mal quellcode rebornX dann wird das sicher einfacher

    EDIT defakto will ich mit meinem text nur sagen das deine Ports völlig unbeeindruckt sind von den aktiven verbindungen von client und server, jede verbindung hat ihren eigenen socket und hat nach beenden des accept NIX mehr mit dem port deines accept am hut.

    MfG und Guten rutsch ins Neue
    Ceos


Anmelden zum Antworten