[C++/winsock] Odpowiedz serwera do wszystkich klientow

Regulamin działu
Kolorowanie składni :
[c][/c], [vb][/vb], [asm][/asm], [delphi][/delphi], [pascal[/pascal], [python][/python], [perl][/perl], [ruby][/ruby], [bash][/bash]

[C++/winsock] Odpowiedz serwera do wszystkich klientow

Postprzez Tomek. 9 paź 2009, o 15:34

Witam mam taki problem.

Mam aplikacje klienta i serwera wszystko śmiga cacy tylko nie wiem jak odpowiedz od serwera wysłać do wszystkich podłączonych klientów ? Jeśli ktoś wie to prosił bym o małe wytłumaczenie sprawy plus trochę kodu jeśli łaska :D

Myślałem o wpisywaniu każdego gniazda do tablicy i później do niej się odwoływać, ale może jest jakiś inny trudniejszy/łatwiejszy sposób na to. Każde info się przyda :)

Tomek.

Tomek.
 
Posty: 2
Dołączył(a): 6 paź 2009, o 20:19

Re: [C++/winsock] Odpowiedz serwera do wszystkich klientow

Postprzez cyber 9 paź 2009, o 16:38

Najlepiej odwolywac sie do tablicy socketow ktore sa aktywne etc innej metody chyba nie ma.

Dam ewentualnie jeszcze przyklad odnosnie uzywania watkow thread aby obsluzyc kazdego klienta:

Kod: Zaznacz cały
  1.  
  2. /***********************************************************************
  3.  threaded-server.cpp - Implements a simple Winsock server that accepts
  4.     connections and spins each one off into its own thread, where it's
  5.     treated as a blocking socket.
  6.  
  7.     Each connection thread reads data off the socket and echoes it
  8.     back verbatim.
  9.  
  10.  Compiling:
  11.     VC++: cl -GX threaded-server.cpp main.cpp ws-util.cpp wsock32.lib
  12.     BC++: bcc32 threaded-server.cpp main.cpp ws-util.cpp
  13.    
  14.  This program is hereby released into the public domain.  There is
  15.  ABSOLUTELY NO WARRANTY WHATSOEVER for this product.  Caveat hacker.
  16. ***********************************************************************/
  17.  
  18. #include "ws-util.h"
  19.  
  20. #include <winsock.h>
  21.  
  22. #include <iostream>
  23.  
  24. using namespace std;
  25.  
  26.  
  27. //// Constants /////////////////////////////////////////////////////////
  28.  
  29. const int kBufferSize = 1024;
  30.        
  31.  
  32. //// Prototypes ////////////////////////////////////////////////////////
  33.  
  34. SOCKET SetUpListener(const char* pcAddress, int nPort);
  35. void AcceptConnections(SOCKET ListeningSocket);
  36. bool EchoIncomingPackets(SOCKET sd);
  37.  
  38.  
  39. //// DoWinsock /////////////////////////////////////////////////////////
  40. // The module's driver function -- we just call other functions and
  41. // interpret their results.
  42.  
  43. int DoWinsock(const char* pcAddress, int nPort)
  44. {
  45.     cout << "Establishing the listener..." << endl;
  46.     SOCKET ListeningSocket = SetUpListener(pcAddress, htons(nPort));
  47.     if (ListeningSocket == INVALID_SOCKET) {
  48.         cout << endl << WSAGetLastErrorMessage("establish listener") <<
  49.                 endl;
  50.         return 3;
  51.     }
  52.  
  53.     cout << "Waiting for connections..." << flush;
  54.     while (1) {
  55.         AcceptConnections(ListeningSocket);
  56.         cout << "Acceptor restarting..." << endl;
  57.     }
  58.  
  59. #if defined(_MSC_VER)
  60.     return 0;   // warning eater
  61. #endif
  62. }
  63.  
  64.  
  65. //// SetUpListener /////////////////////////////////////////////////////
  66. // Sets up a listener on the given interface and port, returning the
  67. // listening socket if successful; if not, returns INVALID_SOCKET.
  68.  
  69. SOCKET SetUpListener(const char* pcAddress, int nPort)
  70. {
  71.     u_long nInterfaceAddr = inet_addr(pcAddress);
  72.     if (nInterfaceAddr != INADDR_NONE) {
  73.         SOCKET sd = socket(AF_INET, SOCK_STREAM, 0);
  74.         if (sd != INVALID_SOCKET) {
  75.             sockaddr_in sinInterface;
  76.             sinInterface.sin_family = AF_INET;
  77.             sinInterface.sin_addr.s_addr = nInterfaceAddr;
  78.             sinInterface.sin_port = nPort;
  79.             if (bind(sd, (sockaddr*)&sinInterface,
  80.                     sizeof(sockaddr_in)) != SOCKET_ERROR) {
  81.                 listen(sd, SOMAXCONN);
  82.                 return sd;
  83.             }
  84.             else {
  85.                 cerr << WSAGetLastErrorMessage("bind() failed") <<
  86.                         endl;
  87.             }
  88.         }
  89.     }
  90.  
  91.     return INVALID_SOCKET;
  92. }
  93.  
  94.  
  95. //// EchoHandler ///////////////////////////////////////////////////////
  96. // Handles the incoming data by reflecting it back to the sender.
  97.  
  98. DWORD WINAPI EchoHandler(void* sd_)
  99. {
  100.     int nRetval = 0;
  101.     SOCKET sd = (SOCKET)sd_;
  102.  
  103.     if (!EchoIncomingPackets(sd)) {
  104.         cerr << endl << WSAGetLastErrorMessage(
  105.                 "Echo incoming packets failed") << endl;
  106.         nRetval = 3;
  107.     }
  108.  
  109.     cout << "Shutting connection down..." << flush;
  110.     if (ShutdownConnection(sd)) {
  111.         cout << "Connection is down." << endl;
  112.     }
  113.     else {
  114.         cerr << endl << WSAGetLastErrorMessage(
  115.                 "Connection shutdown failed") << endl;
  116.         nRetval = 3;
  117.     }
  118.  
  119.     return nRetval;
  120. }
  121.  
  122.  
  123. //// AcceptConnections /////////////////////////////////////////////////
  124. // Spins forever waiting for connections.  For each one that comes in,
  125. // we create a thread to handle it and go back to waiting for
  126. // connections.  If an error occurs, we return.
  127.  
  128. void AcceptConnections(SOCKET ListeningSocket)
  129. {
  130.     sockaddr_in sinRemote;
  131.     int nAddrSize = sizeof(sinRemote);
  132.  
  133.     while (1) {
  134.         SOCKET sd = accept(ListeningSocket, (sockaddr*)&sinRemote,
  135.                 &nAddrSize);
  136.         if (sd != INVALID_SOCKET) {
  137.             cout << "Accepted connection from " <<
  138.                     inet_ntoa(sinRemote.sin_addr) << ":" <<
  139.                     ntohs(sinRemote.sin_port) << "." <<
  140.                     endl;
  141.  
  142.             DWORD nThreadID;
  143.             CreateThread(0, 0, EchoHandler, (void*)sd, 0, &nThreadID);
  144.         }
  145.         else {
  146.             cerr << WSAGetLastErrorMessage("accept() failed") <<
  147.                     endl;
  148.             return;
  149.         }
  150.     }
  151. }
  152.  
  153.  
  154. //// EchoIncomingPackets ///////////////////////////////////////////////
  155. // Bounces any incoming packets back to the client.  We return false
  156. // on errors, or true if the client closed the socket normally.
  157.  
  158. bool EchoIncomingPackets(SOCKET sd)
  159. {
  160.     // Read data from client
  161.     char acReadBuffer[kBufferSize];
  162.     int nReadBytes;
  163.     do {
  164.         nReadBytes = recv(sd, acReadBuffer, kBufferSize, 0);
  165.         if (nReadBytes > 0) {
  166.             cout << "Received " << nReadBytes <<
  167.                     " bytes from client." << endl;
  168.        
  169.             int nSentBytes = 0;
  170.             while (nSentBytes < nReadBytes) {
  171.                 int nTemp = send(sd, acReadBuffer + nSentBytes,
  172.                         nReadBytes - nSentBytes, 0);
  173.                 if (nTemp > 0) {
  174.                     cout << "Sent " << nTemp <<
  175.                             " bytes back to client." << endl;
  176.                     nSentBytes += nTemp;
  177.                 }
  178.                 else if (nTemp == SOCKET_ERROR) {
  179.                     return false;
  180.                 }
  181.                 else {
  182.                     // Client closed connection before we could reply to
  183.                     // all the data it sent, so bomb out early.
  184.                     cout << "Peer unexpectedly dropped connection!" <<
  185.                             endl;
  186.                     return true;
  187.                 }
  188.             }
  189.         }
  190.         else if (nReadBytes == SOCKET_ERROR) {
  191.             return false;
  192.         }
  193.     } while (nReadBytes != 0);
  194.  
  195.     cout << "Connection closed by peer." << endl;
  196.     return true;
  197. }
  198.  


http://tangentsoft.net/wskfaq/examples/ ... server.cpp

Tutaj masz informacje o winsock 2.0:

http://tangentsoft.net/wskfaq/

moze istnieje jakas metoda overloped i/o aby wysylac dane do multi socketow, nie wiem.
Obrazek
gg: 18101618
nie pomagam przy webhackingu

Avatar użytkownika
cyber
 
Posty: 49
Dołączył(a): 5 sie 2009, o 21:23
Lokalizacja: Poznan - Tczew - Trojmiasto

Re: [C++/winsock] Odpowiedz serwera do wszystkich klientow

Postprzez pegaz 9 paź 2009, o 19:32

Zależy jeszcze czy to protokół TCP czy UDP. Dla UDP będzie to łatwiejsze, piszemy do jednego gniazda zmieniając dane w strukturze sockaddr_in. Jeżeli jest to TCP, zależy co powoduje wysłanie wiadomości; należy dobrać odpowiednią komunikację między wątkami.

Avatar użytkownika
pegaz
 
Posty: 17
Dołączył(a): 23 sie 2009, o 19:46

Re: [C++/winsock] Odpowiedz serwera do wszystkich klientow

Postprzez cyber 10 paź 2009, o 10:21

pegaz napisał(a):Jeżeli jest to TCP, zależy co powoduje wysłanie wiadomości; należy dobrać odpowiednią komunikację między wątkami.


Warto zbudowac globalne struktury statusowe, kazdy watek moze sie do nich odwolywac aby posprawdzac flagi pracy calego mechanizmu programu.

Kod: Zaznacz cały
  1.  
  2. typedef struct _STATUS {
  3.  
  4. unsigned long id;//id klienta
  5.  
  6. unsigned long socket;//32 bitowa zmienna na wartosc socketa
  7.  
  8. unsigned long flaga;//flaga pracy danego klienta
  9.  
  10. } STATUS;
  11.  
  12. //binarnie: 000000000000000000000000000001
  13. #define FLAGA_PODLACZONY 0x00000001L
  14. //binarnie 000000000000000000000000000010
  15. #define FLAGA_WYMIANAINFORAMCJI 0x00000002L
  16. //binarnie: 000000000000000000000000000100
  17. #define FLAGA_BLAD 0x00000004L
  18.  
  19. //i tak kolejno kazdy bit zmiennej 32 bitowej
  20. //mozna zdefiniowac 32 rozne stany pracy dla klienta
  21.  
  22. STATUS klienci[999];
  23.  
  24. ////////////////////////////////////
  25. if(klienci[1].flaga & FLAGA_PODLACZONY) {
  26. putout("klient nr: %lu jest podlaczony",klienci[1].id);
  27. }
  28. ////////////////////////////////////
  29.  


Reszta to juz inwencja tworcza. Pozdrowka.
Obrazek
gg: 18101618
nie pomagam przy webhackingu

Avatar użytkownika
cyber
 
Posty: 49
Dołączył(a): 5 sie 2009, o 21:23
Lokalizacja: Poznan - Tczew - Trojmiasto

Re: [C++/winsock] Odpowiedz serwera do wszystkich klientow

Postprzez Tomek. 10 paź 2009, o 14:28

Dzięki za odpowiedzi i pomoc.

Tomek.
 
Posty: 2
Dołączył(a): 6 paź 2009, o 20:19


Powrót do C/C++

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 0 gości

cron