Nachrichten empfangen mit Sockets

Schnoogle

Mitglied
Hallo,

ich bin gerade dabei mit dem Low Level CAN Framework eine Netzwerkanwendung zu implementieren. Das Low Level CAN Framework ist eine Erweiterung für die Sockets unter Linux bzw. ein ergänzenden Protokoll.

Gerade zu den Sockets habe ich eine wohl grundlegende Frage. Ist es von Vorteil, wenn sowohl für das Senden als auch für das Empfangen unterschiedliche Sockets verwende oder kann ich hier auch einen identischen Socket verwenden (weniger Code ...) ?

Nun zu meinem eigentlichen Problem.

Mein aktueller Stand ist, dass ich mit dem Broadcast Manager mehrere zyklisch zu sendende Nachtichten konfiguriert habe. Das zyklische Senden funktioniert bereits. Nun möchte ich aber auch gerne Nachtichten aus dem Netzwerk empfangen. Hierfür möchte ich die Funktion select() verwenden um resourcenschonend auf eine Nachricht zu warten und möchte diese dann mit read auslesen. Leider wird die Funktion select() nicht beendet, was ja wohl bedeutet, dass ich keine Nachticht empfangen habe. Ich habe jedoch mit einem speziellen Hardwaretool mit dem ich das zyklische Senden bereits kontrolliert habe mehrmals eine Nachticht gesendet.

Könnt ihr mit bei meinem Problem vielleicht weiterhelfen.

Hier auch mal ein LINK zu dem Low Level CAN Framework. http://llcf.de/llcf-api-2006-02-20.pdf

Der Broadcast Manager, den ich verwende ist ab Seite 25 beschrieben.
 
Hi,

also die Sockets sind die Schnittstelle vom Netzwerk zum Programm. Wenn du ein Socket öffnest, kannst du sowohl über den Socket senden als auch empfangen. Du kannst immer den selben Socket verwenden. Du brauchst eigentlich nur einen weiteren Socket, wenn du z.B. eine Serverandwendung machen willst, die mehrere Clients auf einmal bedienen soll. Beispiel dafür ist ein Webserver oder so.

Bei deiner eigentlichen Frage kann ich dir nicht genau weiterhelfen, da ich nicht genau weiß was du meinst.

Aber hier mal ein Code mit select() der sicher funktioniert:

Code:
#include <windows.h>

WSADATA WSAData;
SOCKET Socket_1;
SOCKET Socket_2;
sockaddr_in Server_Adresse;
FD_SET fdSet;
char *cIP_Adresse;
int iIP;
int iPortnummer = 1234;
int iErgebnis_Verbindung;
int iErgebnis_SendenEmpfangen;

    WSAStartup(MAKEWORD(2, 0), &WSAData);
    
    Socket_1 = socket(AF_INET, SOCK_STREAM, 0);
    
    if(Socket_1 == -1)
    {
        closesocket(Socket_1);
    }
    else
    {
        Server_Adresse.sin_family = AF_INET;
        Server_Adresse.sin_port = htons(iPortnummer);
        Server_Adresse.sin_addr.s_addr = htons(INADDR_ANY);
        
        iErgebnis_Verbindung = bind(Socket_1, (sockaddr*)&Server_Adresse, sizeof(sockaddr));
        
        if(iErgebnis_Verbindung == -1)
        {
            closesocket(Socket_1);
        }
        else
        {
            iErgebnis_Verbindung = listen(Socket_1, 0);
            
            if(iErgebnis_Verbindung == -1)
            {
                closesocket(Socket_1);
            }
            else
            {
                Socket_2 = INVALID_SOCKET;
                
                while(true)
                {
                    FD_ZERO(&fdSet);
                    FD_SET(Socket_1, &fdSet);
                    
                    if(Socket_2 != INVALID_SOCKET)
                    {
                        FD_SET(Socket_2, &fdSet);
                    }
                    
                    iErgebnis_Verbindung = select(0, &fdSet, NULL, NULL, NULL);
                    
                    if(iErgebnis_Verbindung == SOCKET_ERROR)
                    {
                        closesocket(Socket_1);
                        closesocket(Socket_2);
                    }
                    else
                    {
                        if(FD_ISSET(Socket_1, &fdSet))
                        {
                            if(Socket_2 == INVALID_SOCKET)
                            {
                                Socket_2 = accept(Socket_1, NULL, NULL);
                                
                                if(Socket_2 == -1)
                                {
                                    closesocket(Socket_2);
                                    Socket_2 = INVALID_SOCKET;
                                }
                                else
                                {
                                    //Hier kommst dann dein Code rein, der ausgeführt werden soll, wenn sich ein Client erfolgreich verbunden hat.
                                }
                            }
                            else
                            {
                                Sleep(10);  //und das ist dafür, dass du bei deiner CPU keine 100% auslastung bekommst
                            }
                        }
                    }
                }
            }
        }
    }
 
Zuletzt bearbeitet:
Hallo,

also danke schon mal für die erste Antwort.

Ich versuche nochmal mein Problem genauer zu beschreiben.

Ich habe also einen Socket erstellt und konfiguriere damit den Broadcast Manager. Dabei definiere ich z. B. intervalle in denen der Broadcast Manager bestimmte Nachrichten versenden kann.

Hier ist mal ein Teil aus meinem Code. Leider darf ich den vollständigen Code nicht veröffentlichen.

int socket = socket(PF_CAN, SOCK_DGRAM, CAN_BCM);

//...

connect(socket, (struct sockaddr*)&addr, sizeof(addr));

Das zyklische Senden funktioniert bereits. Ich werde jedoch nicht durch die Funktion Select() informiert, wenn ich eine Nachricht erhalten habe.

Gruß
 
Sorry, mit dem Broadcast Manager kenn ich mich nicht aus und mit Linus auch nicht.
Ich habe gedacht, du hast nur ein select()-Problem.
Hierfür möchte ich die Funktion select() verwenden um resourcenschonend auf eine Nachricht zu warten und möchte diese dann mit read auslesen. Leider wird die Funktion select() nicht beendet, was ja wohl bedeutet, dass ich keine Nachticht empfangen habe.
Dafür habe ich ja bereits meinen Code gepostet. Bei dem anderen kann ich dir nicht weiterhelfen :(
 
Hi
also es ist zwar nicht eigentlich passend zu deiner Fragestellung aber kennt evt jemand von euch ein Buch oder eine Internetseite wo man das mit Sockets lernen kann?
mfg
 
Hallo,

ich habe jetzt auf eine weniger saubere Art zum Funktionieren gebracht. Ich haben einen Thread erstellt der durch Polling die recv()-Funktion aufruft und die Daten alle korrekt empfängt. Jetzt werde ich noch versuchen müssen, es über die select() Methode zu machen, die dann das Polling resourceschonend für mich übernimmt.

Vielen Dank für eure Beträge
 
Zurück