Socket Kommunikation Befehl: select



  • LordTerra schrieb:

    hmmm jo mach ich weil ich gelesen hab das man das machen muss ...

    also laut der webseite (sorry link net mehr da) hies es :
    - man soll den socket aufmachen
    - dann den fdset
    - dann fdzero <--- nur beim 1. mal

    daher hab ich das fdzero dort hingeschrieben wo ich das zwar 1 mal ausführe aber vor dem setvtext und vor isprint

    fdzero must du vor fdset hinschreiben.

    Gruss IchBinNichtSicher



  • Ein fd_set ist nichts weiter, wie eine Datenstruktur, wo du Sockets eintragen kannst. FD_ZERO rufts du nur auf, um sicher zu stellen, dass das fd_set leer ist. Das fd_set selber macht gar nichts. Damit damit etwas geschieht, musst du es an select() übergeben, oder eine andere Funktion, die damit arbeiten kann.
    Eigentlich ist das auch in der MSDN recht umfangreich und ausführlich beschrieben.

    http://msdn.microsoft.com/en-us/library/ms740141(VS.85).aspx



  • Nick Unbekannt schrieb:

    Ein fd_set ist nichts weiter, wie eine Datenstruktur, wo du Sockets eintragen kannst. FD_ZERO rufts du nur auf, um sicher zu stellen, dass das fd_set leer ist. Das fd_set selber macht gar nichts. Damit damit etwas geschieht, musst du es an select() übergeben, oder eine andere Funktion, die damit arbeiten kann.
    Eigentlich ist das auch in der MSDN recht umfangreich und ausführlich beschrieben.

    http://msdn.microsoft.com/en-us/library/ms740141(VS.85).aspx

    So wie ich immer gedacht habe löscht FD_ZERO den Inhalt von fd_set, und das hat er getan nachdem er FD_SET aufruft.

    Er übergibt fd_set leer an select().
    Möglicherweise kommt daher die Fehlermeldung 10038 (Objekt ist kein socket).

    Gruss IchBinNichtSicherr



  • ok wenn ich das zero vor den set mache bekomm ich immer nur "0" als rückgabewert ... egal wie ich es mache ...



  • IchBinNichtSicher schrieb:

    Nick Unbekannt schrieb:

    Ein fd_set ist nichts weiter, wie eine Datenstruktur, wo du Sockets eintragen kannst. FD_ZERO rufts du nur auf, um sicher zu stellen, dass das fd_set leer ist. Das fd_set selber macht gar nichts. Damit damit etwas geschieht, musst du es an select() übergeben, oder eine andere Funktion, die damit arbeiten kann.
    Eigentlich ist das auch in der MSDN recht umfangreich und ausführlich beschrieben.

    http://msdn.microsoft.com/en-us/library/ms740141(VS.85).aspx

    So wie ich immer gedacht habe löscht FD_ZERO den Inhalt von fd_set, und das hat er getan nachdem er FD_SET aufruft.

    Er übergibt fd_set leer an select().
    Möglicherweise kommt daher die Fehlermeldung 10038 (Objekt ist kein socket).

    Gruss IchBinNichtSicherr

    ^^ das problem hierbei ist aber :

    ich rufe das conntect mehrfach auf !!!

    also ich connecte mich führe nen start des druckers aus und disconnecte mich wieder...

    dann concete ich mich um ein set text auszuführen (dieses liefert 2 rückgaben auf recv)

    ich warte die 1. ab und disconnecte mich wieder

    dann conntecte ich mich neu und warte auf das 2. recv

    und ich glaube das geht nicht ... aber da bin ich mir net sicher -.-

    mfg LT



  • IchBinNichtSicher schrieb:

    So wie ich immer gedacht habe löscht FD_ZERO den Inhalt von fd_set,

    Das ist auch richtig so. Ich habe auch nicht auf deinen Beitrag geantwortet. Mir ist nur aufgefallen, dass er im gleichen Kontext die Makros ohne select() benutzt und das ist Unsinn.

    IchBinNichtSicher schrieb:

    Er übergibt fd_set leer an select().
    Möglicherweise kommt daher die Fehlermeldung 10038 (Objekt ist kein socket).

    Eigentlich und da bin ich mir nicht sicher, dürfte er die Fehlermeldung nur bringen, wenn du versuchst einen Nicht-Socket in der Datenstruktur abzulegen. Ob man bei select() zwangsläufig mindestens einen Socket angeben muss weiß ich nicht, aber man kann über das Timeout eine Pause realisieren, welche auch ohne Socket nützlich sein kann.



  • Sich mehrmals zu verbinden ist prinzipiell auch kein Problem. Wobei ich nicht verstehe, warum du die Verbindung beenden musst? Solange dein Druckauftrag läuft kann uns soll sich niemand anders mit dem Drucker verbinden. Wenn du die Verbindung blockierst erhältst du also auch mehr Sicherheit. Ich würde aber mal deinen Code stark überdenken und in kleine Funktionen/Methoden aufteilen. So wie er jetzt da steht, ist er sehr schwer zu lesen und zu verstehen. Damit erhöhst du nur unnötig das Fehlerrisiko. Die Verbindung offen zu lassen würde aber vieles einfacher machen, außer es gibt einen Grund dafür es nicht zu tun?



  • moin

    jo es hat schon nen sinn das ich mich immer nur für ein kommando mit dem drucker verbinde ... das tool was ich schreib is nen überwachungstool und es soll von verschiedenen stellen möglich sein den drucker zu überwachen ... daher muss ich das so programmieren ...

    zum thema unleserlichkeit ... hmmm ganz ehrlich ich dachte eigentlich das ich es eben schon gut gekapselt hab ... was soll ich denn deiner meinung nach noch auslagern ???

    mfg lt



  • Da musst du selber mal drüber schauen, was man zusammen fassen kann oder evtl. sogar wiederverwenden. Vielleicht muss man auch Sachen allgemeiner formulieren, damit sie öfters angewandt werden können. Verringert aber trotzdem die Möglichkeiten von Fehlern enorm. Zuviel sollte man natürlich auch nicht zusammenfassen, nicht dass die Fallunterscheidungen überhand nehmen. Wenn du meinst es ist gut gegliedert und es kann auch nichts mehr zusammengefasst werden, dann kann du immer noch die einzelnen Schritte in Funktionen packen und in deiner Funktion aufrufen.
    Das ist aber nur ein Vorschlag, ich will dir nicht vorschreiben, wie du deine Programme zu schreiben hast. Was für dich sicher auch noch interessant sein könnte ist das Stichwort Objektorientierung.
    Wenn du dir ein Objekt Drucker anlegst, dann kannst du dort im Konstruktor deine Initialisierung vornehmen und den Destruktor alles wieder aufräumen lassen. Heißt du musst dich nicht mehr selber darum kümmern. Dem Objekt verpasst du dann noch eine Methode zum Senden, welche kurzfristig die Verbindung herstellt und vielleicht eine zum Lesen. Ich kenne jetzt aber dein Anforderungsprofil auch nicht.
    Durch einen übersichtlicheren Quelltext hättest du mich zum Beispiel auch dazu animieren können, ihn einmal zu lesen. Um zu verstehen was du wirklich machen willst. Wenn ich erst ewig lange grübeln muss, dann hab ich dazu keine Lust mehr. Wobei ich es auch gar nicht erst versucht habe, weil du mich vorher schon abgeschreckt hast. So kompliziert muss also dein Ablauf gar nicht sein.



  • hmmm mag sein das es auch einfacher geht ...

    aber naja so schwierig find ich meinen quellcode gar net ...
    erst kommt n bissi was zur socket-verbindung
    dann kommen die befehle die in senden und empfangen aufgegliedert sind
    und dann kommt n bissi dicsonncet kram also find den code nu net so unübersichtlich ... aber is sicher ansichtssache 🙂

    aber problem besteht immer noch ...
    also im mom hab ich das fd_zero vor den fd_set gesetzt
    (wohlgemerkt bei jeder komunikation)

    ergebnis= ich bekomm immer ne 0 als returnwert von select()

    is also auch net das was ich will ...



  • Hallo

    Zum einen, wenn 0 zurückkommt bedeutet das nur das dein Timeout von 1 sec abgelaufen ist und mehr nicht. Also entweder erhöst du deinen Timeout oder du musst die Methode mehrfach in einer Schleife aufrufen. So in etwas (Vorsicht nur PseudoCode):

    while (empfangen) {
      FD_ZERO(fdset);
      FD_SET(socket, &fdset);
      ret = select(0, &fdset, null, null, &tv);
      if (0 < ret) {
        if (FD_ISSET(socket, &fdset)) {
          // es kamm was an
          ret = recv(....)
          if (SOCKET_ERROR != ret) {
            // Daten auswerten
          }
          else {
            // Die Verbindung wurde getrennt
          }
          empfangen = true;
        }
      }
    } // while (....
    

    Nur so nebenbei, select ist ausgelegt um auf mehrere Sockets gleichzeitig zu hören, du könntest auch jederzeit denn Socket entsprechend umstellen das er Asynchron läuft, dann musst du die Wartezeit zwischen den Aufrufen nur selber mit Sleep einbauen. Aber um die While-Schleife wirst nicht rumkommen.

    MfG Marco



  • danke dir marco ...

    die schleife hatte ich eh vor zu benutzen

    mein programm ruft ja den cmdserver auf ...

    so nach dem motto:

    CString cmd="BLUHM_ON";
    if(cmdServer(cmd, ip , port)){
    
      cmd="BLUHM_SET_VTEXT";
      if(cmdServer(cmd, ip , port)){
    
        do{
          cmd="BLUHM_ISPRINT";
          if(cmdServer(cmd, ip , port)){
            AfxMessageBox("Hat gedruckt mach noch was");
          }
        }while("bis ich sage stop");
      }
    }
    

    mfg kala


Anmelden zum Antworten