Jak wyslac dane do serwera ?

0

Sciągnałem kod servera i kod clienta. Server i client działa na zasadzie:

  1. server nasluchuje na danym porcie
  2. client laczy sie z serverem
  3. server czeka na odebranie waidomosci
  4. client wysyla wiadomosc i czeka na odbior wiadomosci od serwer
  5. servwer czeka na wpisanie wiadomosci zeby ja odeslac do klienta

Chcialem przerobic tak zeby server nasluchiwal caly czas wiec zapetlilem program i
teraz jest ok jesli chodzi o odbieranie danych od kliku klinetow ktorzy sie polacza.
Ale w klinecie jest tak ze jak sie polacze i wysle wiadomosc to server ja odbierze
ale jak znowu wpisze kolejna to drugi raz juz jej nie widac. Musze sie rozlaczyc i
polaczyc ponownie. czy wiece jak mozna to przerobic by dzialalo tak ze klinet
moze wysylac dowolna ilosc wiadomości.

w kodzie dodalem petle while(true) ale nadal nie dziala

 #include <winsock.h>
#include <iostream.h>
#include <stdlib.h>
#include <string.h>

//using namespace std;

int main(int argc, int **argv)
{
   WSADATA wsda;				// informacja zwrocona przez WSAStartup
   struct hostent *host;		// informacja o serwerze
   char szMessage[80];			// komunikat
   int iMessageLen;
   int ret;
   char szInBuffer[128];
   int iBufferLen;
   char szAddress[64];
   int iPort;

   SOCKET s;		         // uzywane gniazdo
   SOCKADDR_IN addr;	      // adres hosta


   // pobranie adresu IP
   cout << "Podaj adres IP do ktorego wyslac (np. 127.0.0.1) ...";
   cin.getline(szAddress,64,'\n');

   // port na ktorym sie komunikujemy (0...65535)
   iPort = 1000;



   // zaladuj WinSock w wersji 2.2
   WSAStartup(MAKEWORD(2,2), &wsda);

   // stworzenie gniazda TCP
   s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);

   // sprawdzenie bledu
   if(s == SOCKET_ERROR)
   {
      cout << "Blad przy inicjalizacji gniazda : " << WSAGetLastError() << endl;
      system("PAUSE");
      exit(1);
   }

   // informacja o hoscie
   addr.sin_family = AF_INET;
   addr.sin_port = htons(iPort);
   addr.sin_addr.s_addr = inet_addr(szAddress);

   if(addr.sin_addr.s_addr == INADDR_NONE) 	// jesli nie podano numeru IP, to odnajdz go z DNS
   {
      host = NULL;
      cout << "Szukam hosta..." << endl;
      host = gethostbyname(szAddress);	// pobierz numer IP i go zachowaj
      if(host == NULL)
      {
         cout << "Nieznany host." << endl;
         system("PAUSE");
         exit(1);
      }
      memcpy(&addr.sin_addr, host->h_addr_list[0], host->h_length);
      cout << "OK." << endl;
   }

   // laczenie z serwerem
   cout << "Laczenie z hostem " << szAddress << " na porcie " << iPort << endl;
   ret = connect(s, (struct sockaddr *) &addr, sizeof(addr));

   // sprawdzenie bledu
   if(ret == SOCKET_ERROR)
   {
      cout << "Blad przy laczeniu z serwerem : " << WSAGetLastError() << endl;
      system("PAUSE");
	  exit(1);
   }

    while(true) {

     // pobranie komunikatu do bufora
   cout << "Wpisz komunikat ...";
   cin.getline(szMessage,80,'\n');

   // dlugosc komunikatu
   iMessageLen = strlen(szMessage);

   // wyslanie komunikatu
   cout << "Wysylanie pakietu..." << endl;
   ret = send(s, szMessage, iMessageLen, 0);

   // sprawdzenie bledu
   if(ret == SOCKET_ERROR)
   {
      cout << "Blad przy wysylaniu komunikatu : " << WSAGetLastError() << endl;
      system("PAUSE");
      exit(1);
   }

    }

   // odbior komunikatu zwrotnego
   cout << "Oczekiwanie na komunikat zwrotny..." << endl;
   ret = recv(s, szInBuffer, sizeof(szInBuffer), 0);

   // sprawdzenie bledu
   if(ret == SOCKET_ERROR)
   {
      cout << "Blad przy odbiorze komunikatu zwrotnego : " << WSAGetLastError() << endl;
      system("PAUSE");
      exit(1);
   }

   // wyswietlenie komunikatu zwrotnego
   iBufferLen = ret;
   szInBuffer[iBufferLen] = '\0';
   cout << "Otrzymano komunikat o tresci \"" << szInBuffer << "\" od hosta " << szAddress << endl;

   // zamkniecie gniazda
   closesocket(s);

   // zamkniecie WinSock
   WSACleanup();

   system("PAUSE");

   return 0;
}
0

Kod jest TRAGICZNY. A jakbyś go sformatował to byś wiedział w czym problem:

#include <winsock.h>
#include <iostream.h>
#include <stdlib.h>
#include <string.h>

//using namespace std;

int main(int argc, int **argv)
{
    WSADATA wsda;                                // informacja zwrocona przez WSAStartup
    struct hostent *host;                // informacja o serwerze
    char szMessage[80];                        // komunikat
    int iMessageLen;
    int ret;
    char szInBuffer[128];
    int iBufferLen;
    char szAddress[64];
    int iPort;

    SOCKET s;                         // uzywane gniazdo
    SOCKADDR_IN addr;              // adres hosta

    // pobranie adresu IP
    cout << "Podaj adres IP do ktorego wyslac (np. 127.0.0.1) ...";
    cin.getline(szAddress,64,'\n');

    // port na ktorym sie komunikujemy (0...65535)
    iPort = 1000;

    // zaladuj WinSock w wersji 2.2
    WSAStartup(MAKEWORD(2,2), &wsda);

    // stworzenie gniazda TCP
    s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);

    // sprawdzenie bledu
    if(s == SOCKET_ERROR)
    {
        cout << "Blad przy inicjalizacji gniazda : " << WSAGetLastError() << endl;
        system("PAUSE");
        exit(1);
    }

    // informacja o hoscie
    addr.sin_family = AF_INET;
    addr.sin_port = htons(iPort);
    addr.sin_addr.s_addr = inet_addr(szAddress);

    if(addr.sin_addr.s_addr == INADDR_NONE)         // jesli nie podano numeru IP, to odnajdz go z DNS
    {
        host = NULL;
        cout << "Szukam hosta..." << endl;
        host = gethostbyname(szAddress);        // pobierz numer IP i go zachowaj
        if(host == NULL)
        {
            cout << "Nieznany host." << endl;
            system("PAUSE");
            exit(1);
        }
        memcpy(&addr.sin_addr, host->h_addr_list[0], host->h_length);
        cout << "OK." << endl;
    }

    // laczenie z serwerem
    cout << "Laczenie z hostem " << szAddress << " na porcie " << iPort << endl;
    ret = connect(s, (struct sockaddr *) &addr, sizeof(addr));

    // sprawdzenie bledu
    if(ret == SOCKET_ERROR)
    {
        cout << "Blad przy laczeniu z serwerem : " << WSAGetLastError() << endl;
        system("PAUSE");
        exit(1);
    }

    while(true)
    {
        // pobranie komunikatu do bufora
        cout << "Wpisz komunikat ...";
        cin.getline(szMessage,80,'\n');

        // dlugosc komunikatu
        iMessageLen = strlen(szMessage);

        // wyslanie komunikatu
        cout << "Wysylanie pakietu..." << endl;
        ret = send(s, szMessage, iMessageLen, 0);

        // sprawdzenie bledu
        if(ret == SOCKET_ERROR)
        {
            cout << "Blad przy wysylaniu komunikatu : " << WSAGetLastError() << endl;
            system("PAUSE");
            exit(1);
        }

    }

    // odbior komunikatu zwrotnego
    cout << "Oczekiwanie na komunikat zwrotny..." << endl;
    ret = recv(s, szInBuffer, sizeof(szInBuffer), 0);

    // sprawdzenie bledu
    if(ret == SOCKET_ERROR)
    {
        cout << "Blad przy odbiorze komunikatu zwrotnego : " << WSAGetLastError() << endl;
        system("PAUSE");
        exit(1);
    }

    // wyswietlenie komunikatu zwrotnego
    iBufferLen = ret;
    szInBuffer[iBufferLen] = '\0';
    cout << "Otrzymano komunikat o tresci \"" << szInBuffer << "\" od hosta " << szAddress << endl;

    // zamkniecie gniazda
    closesocket(s);

    // zamkniecie WinSock
    WSACleanup();

    system("PAUSE");

    return 0;
}

Zauważ ze wiadomość zwrotną odbierasz tylko raz bo jest poza pętlą...

0

wiem wiem bo ja nie chce zeby klient odbieral wiadomosc zwrotna chce zeby mogl wysylac wiadomosci do serwera ale nie chce zeby za kazdym razem sie znim laczyl tylko zeby na tym ustanowioanym polaczeniu mogl wysylac w petli te wiadomosci to jak to zrobic ?

0

W takim razie masz to napisane poprawnie, klient będzie wysyłał do serwera wielokrotnie wiadomości. Ale zapewne po stronie serwera tego nie przewidziałeś...

0

Server wyglada tak:

#include <iostream.h>
#include <winsock.h>
#include <stdlib.h>
#include <string.h>
#include<iostream.h>


//using namespace std;

int main(int argc, int **argv)
{
   WSADATA wsda;		      // informacja zwrocona przez WSAStartup
   char szRepMessage[80];     // komunikat zwrotny
   int iMessageLen;
   int ret;
   char szInBuffer[128];		// bufor na otrzymany komunikat
   int iBufferLen;
   int iPort, iAddrLen;

   SOCKET sListen, sClient;			// gniazdo dla nasluchu oraz do klienta
   SOCKADDR_IN addr,remote_addr;    // interfejs lokalny oraz polaczonego klienta


   // port na ktorym sie komunikujemy (0...65535)
   iPort = 1000;

   // zaladuj WinSock w wersji 2.2
   WSAStartup(MAKEWORD(2,2), &wsda);

   // stworzenie gniazda TCP
   sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);

   // sprawdzenie bledu
   if(sListen == SOCKET_ERROR)
   {
      cout << "Blad przy inicjalizacji gniazda : " << WSAGetLastError() << endl;
      system("PAUSE");
	  exit(1);
   }

   // laczenie gniazda z adresem/portem
   addr.sin_family = AF_INET;
   addr.sin_port = htons(iPort);
   addr.sin_addr.s_addr = htonl(INADDR_ANY);
   ret = bind(sListen, (struct sockaddr *) &addr, sizeof(addr));

   // sprawdzenie bledu
   if(ret == SOCKET_ERROR)
   {
      cout << "Blad przy wiazaniu gniazda : " << WSAGetLastError() << endl;
      system("PAUSE");
      exit(1);
   }
   while(true) {
   // ustaw tryb nasluchu
   ret = listen(sListen, 10);

   // sprawdzenie bledu
   if(ret == SOCKET_ERROR)
   {
      cout << "Blad przy trybie nasluchu : " << WSAGetLastError() << endl;
      system("PAUSE");
      exit(1);
   }

   // oczekiwanie na polaczenie
   cout << "Oczekiwanie na polaczenie (nacisnij CTRL-C zeby przerwac)..." << endl;
   iAddrLen = sizeof(remote_addr);
   sClient = accept(sListen, (struct sockaddr *) &remote_addr, &iAddrLen);

   // sprawdzenie bledu
   if(sClient == SOCKET_ERROR)
   {
      cout << "Blad przy nawiazywaniu polaczenia : " << WSAGetLastError() << endl;
      system("PAUSE");
      exit(1);
   }

   cout << "Polaczono z hostem " << inet_ntoa(remote_addr.sin_addr) << endl;



   // odbior komunikatu
   cout << "Oczekiwanie na odpowiedz..." << endl;
   ret = recv(sClient, szInBuffer, sizeof(szInBuffer), 0);

   // sprawdzenie bledu
   if(ret == SOCKET_ERROR)
   {
      cout << "Blad przy odbiorze komunikatu " << WSAGetLastError() << endl;
      //system("PAUSE");
     // exit(1);
   }

   // wyswietlenie komunikatu od klienta
   iBufferLen = ret;
   szInBuffer[iBufferLen] = '\0';
   cout << "Otrzymano komunikat o tresci \"" << szInBuffer << "\"" << endl;

     }

   // wczytanie i wyslanie komunikatu zwrotnego
   cout << "Wpisz komunikat zwrotny...";
   cin.getline(szRepMessage,80,'\n');
   iMessageLen = strlen(szRepMessage);
   ret = send(sClient, szRepMessage, iMessageLen, 0);

   // sprawdzenie bledu
   if(ret == SOCKET_ERROR)
   {
      cout << "Blad przy wysylaniu komunikatu zwrotnego : " << WSAGetLastError() << endl;
      system("PAUSE");
      exit(1);
   }





   // zamkniecie gniazda
   closesocket(sClient);

   // zamkniecie WinSock
   WSACleanup();

   system("PAUSE");

   return 0;

}
 

w sumie nie wiem co moze byc zle ze nie odbiera komuniaktow ?

0

W twoim kodzie serwera odbierasz tylko jedną wiadomość od klienta a potem znów oczekujesz na połączenia. Możesz to zrobić na wątkach:

  • socket który dostajesz z accept() przekazujesz do wątku który odczytuje sobie wiadomości w pętli
  • główny wątek programu jedynie odbiera połączenia przez accept() i odpala nowe wątki.
0

Proponuje poczytać http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio.html

stwierdzisz, że te wypociny przyniosą Ci gorsze efekty i więcej pracy

1 użytkowników online, w tym zalogowanych: 0, gości: 1