Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

05.01.2014, 13:01

Winsock fdSet im Client

Hey Leute


Ich habe ein problem, trotz das ich in meinem Winsock Client ein FdSet verwende, hält das Programm bei recv an .


Hier ist der Teil, an dem das Programm hängt

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
      if(FD_ISSET(s,&fdSet))
      {
                  rc=recv(s,buf,256,0);   //Hier bleibt er hängen
        // prüfen ob die verbindung geschlossen wurde oder ein fehler auftrat
        if(rc==0 || rc==SOCKET_ERROR)
        {
          closesocket(s); // socket schliessen

        }
        else
        {
          buf[rc]='\0';
            cout << "Server sendete   :"<<buf << endl;
        }

          if(kbhit())
         {

             char c=getch();
             if(static_cast<int>(c)==13)
             {
                               buf[pos]='\0';
                        send(s,buf,sizeof(buf),0);
                        pos=0;
             }
             else
             {
             buf[pos]=c;
             pos++;

             }

         }


      }


Ich habe das ganze wie beim server unterteilt, es sollte also eigentlich funktionieren ^^ was es aber nicht tut.

Ich hoffe ihr könnt mir da helfen

Gruß Leri

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

2

05.01.2014, 13:38

Tja, wie wird denn fdSet vorher befüllt und verwendet? Ist es korrekt initialisiert?
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

3

05.01.2014, 13:48

Hier der ganze Quellcode, es sollte eigentlich alles richtig sein, falls es beim Server zum Client keine veränderung, ausser connect beim fdset gibt

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <windows.h>
#include <winsock2.h>
#include <stdio.h>
 #include<cstdio>
 #include<conio.h>
#include<iostream>
using namespace std;

//Prototypen
int startWinsock(void);

int main()
{
        int pos=0;
  long rc;
  SOCKET s;
  SOCKADDR_IN addr;
  char buf[256];
    FD_SET fdSet;

  // Winsock starten
  rc=startWinsock();
  if(rc!=0)
  {
    printf("Fehler: startWinsock, fehler code: %ld\n",rc);
    return 1;
  }
  else
  {
    printf("Winsock gestartet!\n");
  }

  // Socket erstellen
  s=socket(AF_INET,SOCK_STREAM,0);
  if(s==INVALID_SOCKET)
  {
    printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError());
    return 1;
  }
  else
  {
    printf("Socket erstellt!\n");
  }

  // Verbinden
  memset(&addr,0,sizeof(SOCKADDR_IN)); // zuerst alles auf 0 setzten
  addr.sin_family=AF_INET;
  addr.sin_port=htons(12345); // wir verwenden mal port 12345
  addr.sin_addr.s_addr=inet_addr("127.0.0.1"); // zielrechner ist unser eigener

  rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR));
  FD_SET(s,&fdSet);
  if(rc==SOCKET_ERROR)
  {
    printf("Fehler: connect gescheitert, fehler code: %d\n",WSAGetLastError());
    return 1;
  }
  else
  {
    printf("Verbunden mit 127.0.0.1..\n");

  }
  // Daten austauschen
  while(1)
  {
    FD_ZERO(&fdSet); // Inhalt leeren
    FD_SET(s,&fdSet); // Den Socket der verbindungen annimmt hinzufüg
    rc = select(s+ 1, NULL, &fdSet, NULL, NULL);
    if(rc==SOCKET_ERROR)
    {
      printf("Fehler: select, fehler code: %c\n",WSAGetLastError());
      return 1;
    }
      if(FD_ISSET(s,&fdSet))
      {
                  rc=recv(s,buf,256,0);
        // prüfen ob die verbindung geschlossen wurde oder ein fehler auftrat
        if(rc==0 || rc==SOCKET_ERROR)
        {
          closesocket(s); // socket schliessen

        }
        else
        {
          buf[rc]='\0';
            cout << "Server sendete   :"<<buf << endl;
        }

          if(kbhit())
         {

             char c=getch();
             if(static_cast<int>(c)==13)
             {
                               buf[pos]='\0';
                        send(s,buf,sizeof(buf),0);
                        pos=0;
             }
             else
             {
             buf[pos]=c;
             pos++;

             }

         }


      }
  }
  closesocket(s);
  WSACleanup();
  return 0;

}

int startWinsock(void)
{
  WSADATA wsa;
  return WSAStartup(MAKEWORD(2,0),&wsa);
}

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

4

05.01.2014, 14:36

Schau dir den select Aufruf nochmal genauer an. Ich glaube da ist dir einen kleinen aber feinen Fehler unterlaufen.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

5

05.01.2014, 14:39

ja hab mir select grad angeschaut, wenn ich nun aber select(0,&fdset,&fdset,&fdset,NULL) dann klappts auch nciht, oder muss ich für jeden der Parameter ein eigenes fdset anlegen?

klappt so leider auch nicht

C-/C++-Quelltext

1
rc = select(0, &fdSet, &fdSet, &fdSet, NULL);

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

6

05.01.2014, 14:50

Für jeder der in-out brauchst du soweit ich weiß ein eigenes Set. Aber willst du denn bei recv lesen,schreiben oder einen Fehler abfragen?
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

7

05.01.2014, 14:53

bei redv soll die nachricht vom server empfangen werden und danach kommt eine abfrage, ob eine Taste auf der Tastatur gedrückt wurde, sollte diese Taste enter gewesen sein, so sollte der Client eine Nachricht an den Server senden, aber allein beim abfragen bei recv, ob eine Nachricht vom Server kam, bleibt er hängen, egal wie ich die Parameter angebe ^^

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

8

05.01.2014, 15:13

C-/C++-Quelltext

1
rc = select(0, &fdSet, NULL, NULL, NULL);

schon versucht?
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

9

05.01.2014, 15:30

ja habe ich schon versucht, aber da geht er noch nicht mal in die abfrage fs_Isset ^^

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

10

05.01.2014, 15:34

Und was verleitet dich zu der Annahme, dass das nicht das gewünschte Verhalten ist?
Bist du dir denn darüber im Klaren was du eigentlich erreichen willst? Denn Isset geht natürlich nur dann in den Block, wenn es Daten zu Lesen gibt-sollte es denn schon Daten zum Lesen geben?
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

Werbeanzeige