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

11

05.01.2014, 15:37

Hier nochmal beide cpp Dateien

Server:

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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <windows.h>
#include <winsock2.h> // bei manchan compilern muss man nur windows.h includieren (zB VC++)
#include <stdio.h>

#define MAX_CLIENTS 10

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

int main()
{
  long rc;
  SOCKET acceptSocket;
  //SOCKET connectedSocket;
  SOCKADDR_IN addr;
  char buf[256];
  char buf2[300];
  // zusätzliche Variabeln
  FD_SET fdSet;
  SOCKET clients[MAX_CLIENTS];
  int i;

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

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

  // Socket binden
  memset(&addr,0,sizeof(SOCKADDR_IN));
  addr.sin_family=AF_INET;
  addr.sin_port=htons(12345);
  addr.sin_addr.s_addr=INADDR_ANY; // gewisse compiler brauchen hier ADDR_ANY
  rc=bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));
  if(rc==SOCKET_ERROR)
  {
    printf("Fehler: bind, fehler code: %d\n",WSAGetLastError());
    return 1;
  }
  else
  {
    printf("Socket an port 12345 gebunden\n");
  }

  // In den listen Modus
  rc=listen(acceptSocket,10);
  if(rc==SOCKET_ERROR)
  {
    printf("Fehler: listen, fehler code: %d\n",WSAGetLastError());
    return 1;
  }
  else
  {
    printf("acceptSocket ist im listen Modus....\n");
  }

  for(i=0;i<MAX_CLIENTS;i++)
  {
    clients[i]=INVALID_SOCKET;
  }

  while(1)
  {
    FD_ZERO(&fdSet); // Inhalt leeren
    FD_SET(acceptSocket,&fdSet); // Den Socket der verbindungen annimmt hinzufügen

    // alle gültigen client sockets hinzufügen (nur die die nicht INVALID_SOCKET sind)
    for(i=0;i<MAX_CLIENTS;i++)
    {
      if(clients[i]!=INVALID_SOCKET)
      {
        FD_SET(clients[i],&fdSet);
      }
    }

    rc=select(0,&fdSet,NULL,NULL,NULL); // nicht vergessen den ersten parameter bei anderen betriebssystem anzugeben
    if(rc==SOCKET_ERROR)
    {
      printf("Fehler: select, fehler code: %c\n",WSAGetLastError());
      return 1;
    }

    // acceptSocket is im fd_set? => verbindung annehmen (sofern es platz hat)
    if(FD_ISSET(acceptSocket,&fdSet)) {
      // einen freien platz für den neuen client suchen, und die verbingung annehmen
      for(i=0;i<MAX_CLIENTS;i++)
      {
        if(clients[i]==INVALID_SOCKET)
        {
          clients[i]=accept(acceptSocket,NULL,NULL);
          printf("Neuen Client angenommen (%d)\n",i);
          break;
        }
      }
    }

    // prüfen wlecher client sockets im fd_set sind
    for(i=0;i<MAX_CLIENTS;i++)
    {
      if(clients[i]==INVALID_SOCKET)
      {
        continue; // ungültiger socket, d.h. kein verbunder client an dieser position im array
      }
      if(FD_ISSET(clients[i],&fdSet))
      {
        rc=recv(clients[i],buf,256,0);
        // prüfen ob die verbindung geschlossen wurde oder ein fehler auftrat
        if(rc==0 || rc==SOCKET_ERROR)
        {
          printf("Client %d hat die Verbindung geschlossen\n",i);
          closesocket(clients[i]); // socket schliessen
          clients[i]=INVALID_SOCKET; // seinen platz wieder freigeben
        }
        else
        {
          buf[rc]='\0';
          // daten ausgeben und eine antwort senden
          printf("Client %d hat folgendes gesandt: %s\n",i,buf);
          // antwort senden
          sprintf(buf2,"Du mich auch %s\n",buf);
          send(clients[i],buf2,(int)strlen(buf2),0);
        }
      }
    }
  }
  system("pause");
  WSACleanup();
  return 0;
}




Client

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(0, &fdSet, NULL, 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;
        }
    rc = select(1, NULL, &fdSet, NULL, NULL);
          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);
}

12

05.01.2014, 15:38

Na klar schuldigung, kann ja garnicht klappen, aber jetzt wäre die andere frage, sollte ich jetzt ein zweites fdset machen zum schreiben oder kann ich das aus dem block lösen und ohne zweites fd set arbeiten?^^

13

05.01.2014, 15:42

hast schon recht, das er diesen dann nicht ausführt, aber er führt auch nicht die while schleife aus, das heißt ja, das er irgendwo hängt, habe jetzt den keyhit teil ausserhalb von fd_isset gesteckt, und er gibt nichts aus

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

14

05.01.2014, 16:02

Wo genau er "hängen" bleibt kannst du ja per Debugger rausfinden. Falls du dich mit diesem noch nicht vertraut gemacht hast, wäre das ein guter Augenblick es nun zu tun.
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.

15

05.01.2014, 16:15

er bleibt an der select funktion hängen

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

16

05.01.2014, 16:21

Was würdest du denn für ein Verhalten erwarten?
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.

17

05.01.2014, 16:34

das er nach select weitermacht ^^ und zumindestens die while schleife ausführt

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

18

05.01.2014, 16:42

"If time-out is a null pointer, select will block indefinitely until at least one descriptor meets the specified criteria." quelle: msdn
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.

19

05.01.2014, 16:45

die delays gehen aber dann für beide abfragen oder ? also fürs lesen und schreiben?

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

20

05.01.2014, 17:30

Diese Frage verstehe ich ehrlich gesagt nicht. Der Timeoutparameter gilt halt für den entsprechenden select Aufruf. Select blockiert solange, bis der timeout abgeluafen ist, oder mindestens bei einem der übergebenen sockets die entsprechende Bedingung zutrifft.
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