[C/WinSock] funckja select()

0

Witam. Mam kolejny problem tym razem zwiazany z funkcja select(), nie rozumiem dlaczego zwraca wartosc -1 i niewiem co oznacza zwrocenie tej wartosci przez select. Niewiem rowniez czy dobrze jest napisany serwer poniewaz wedlug mnie chyba powinien obslugiwac 2 polaczenia, a obsluguje ich nieskonczonosc. Prosilbym o wskazanie przyczyny tych bledow i wyjasnienie niejasnosci. Nie lece na forum z kazdym problemem ktorego nie umiem rozwiazac, ale najpierw staram sie sam cos poradzic, ale w tym przypadku nie dam rady bo nawet niewiem co oznacza zwrocona taka wartosc, google niewiele pomoglo w tej kwetsi.
Kod serwera

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winsock2.h>

int main()
{
  WSADATA WData;
  SOCKET sock;
  SOCKET nowy;
  SOCKADDR_IN sin;
  SOCKADDR_IN cin;
  FD_SET fds;
  TIMEVAL tv;
  int s, i = 0;
  char buf[1024] = {0};

  printf("                      Serwer TCP\n");
  printf("------------------------------------------------------\n");

  if(WSAStartup(MAKEWORD(2,0), &WData) != 0)  {
    printf("Blad inicjalizacji biblioteki WinSock2.\n");
    printf("Kod bledu: %d\n", WSAGetLastError());
    system("PAUSE");
    return 1;
  }

  sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

  sin.sin_family = AF_INET;
  sin.sin_port = htons(3000);
  sin.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
  memset(sin.sin_zero, 0, 8);

  bind(sock, (SOCKADDR*)&sin, sizeof(SOCKADDR));

  if(listen(sock, 1) != 0)  {
    printf("Blad w instalacji serwera.\n");
    printf("Kod bledu: %d\n", WSAGetLastError());
    system("PAUSE");
    return 1;
  }

  fds.fd_count = 2;
  fds.fd_array[0] = sock;
  tv.tv_sec = 1;
  int ret = select(0, &fds, NULL, NULL, &tv);

  while(1)  {
    if(ret == SOCKET_ERROR)  {
      s = sizeof(cin);
      nowy = accept(sock, (SOCKADDR*)&cin, &s);
      if(nowy == INVALID_SOCKET )  {
        printf("Blad funkcji accept.\n");
        printf("Kod bledu: %d\n", WSAGetLastError());
        system("PAUSE");
        return 1;
      }
      else  {
        printf("Funkcja select zwrocila: %d.\n", ret);
        printf("Nawiazano polaczenie z: %s\n", inet_ntoa(cin.sin_addr));
        recv(nowy, buf, 1024, 0);
        printf("Odebrano: %s\n", buf);
      }
    }
    else  {
      break;
    }
  }

  closesocket(sock);
  WSACleanup();

  printf("\n");
  system("PAUSE");
  return 0;
}
0

Juz czytalem to i sie przydalo jak programowalem sockety pod gentoo ;]
Teraz sie tylko przydalo, bo wiem co oznacza -1, a takto <ort>niewiem</ort> czy uzywajac winsock mam korzystac z funkcji FD_SET, FD_ZERO, FD_ISSET, czy tylko wypelnic strukture fd_set i timeval oraz <ort>niewiem</ort> czy jak rzutuje do typu int typ socket to dostane kolejny numer deskryptora i jeszcze nie do konca ladnie to sie przeklada na winsockety. Prosilbym o wyjasnienie tych watpliwosci lub o podanie jakies innego przykladu, naprawde dlugo szukalem na google i nic ciekawego nie znalazlem dlatego sie pytam tutaj jak mam poprawic program serwer, aby dzialal poprawnie.

Kombinuje i kombinuje dalej :D Niestety select caly czas zwraca SOCKET_ERROR ;/ Prosze o pomoc !
Oto kod glownej petli:

while(1)  {
    i++;
    s = sizeof(cin);
    nowy = accept(sock, (SOCKADDR*)&cin, &s);
    if(nowy != INVALID_SOCKET) {
      fds.fd_array[i] = nowy;
      fds.fd_count = 2;
      tv.tv_sec = 1;
      int lg = select(0, &fds, NULL, NULL, &tv);
      if(lg != SOCKET_ERROR)  {
        while(lg > 0)  {
          lg--;
          printf("Funkcja select zwrocila: %d.\n", lg);
          printf("Nawiazano polaczenie z: %s\n", inet_ntoa(cin.sin_addr));
          recv(nowy, buf, 1024, 0);
          printf("Odebrano: %s\n", buf);
        }
      }
      else {
        printf("Funkcja select zwrocila: %d.\n", lg);
        break;
      }
    }
    else  {
      printf("Blad funkcji accept.\n");
      printf("Kod bledu: %d\n", WSAGetLastError());
      system("PAUSE");
      return 1;
    }
  }

PS. piszac ze programowalem po gentoo mam na mysli prosty serwerek i kliencik nawet bez uzycia select ;)

Doszedlem do tego ze moj serwer obsluguje <ort>nie skonczona</ort> liczbe polaczen(chyba ;p), ale jesli jakis klient probuje wyslac w petli kilka razy te same dane to niestety serwer nie radzi sobie z ich odbiorem, znaczy odbiera tylko pierwszy pakiet danych, poczym wyswietla je. Funkcja select zwraca 1, wydaje mi sie ze to jest liczba gniazd :) Pozostaje problem jak to zrobic, aby serwer odbieral wszystkie dane. Prosze o pomoc. Bede bardzo wdzieczny.
Oto kod glownej petli serwera po modyfikacjach, reszta bez zmian:

 while(1)  {
    fds.fd_array[0] = sock;
    fds.fd_count = 1;
    tv.tv_sec = 10;
    int lg = select(0, &fds, NULL, NULL, &tv);
    if(lg > 0)  {
      s = sizeof(cin);
      nowy = accept(sock, (SOCKADDR*)&cin, &s);
      if(nowy != INVALID_SOCKET) {
        printf("Funkcja select zwrocila: %d.\n", lg);
        printf("Nawiazano polaczenie z: %s\n", inet_ntoa(cin.sin_addr));
        recv(nowy, buf, 1024, 0);
        printf("Odebrano: %s\n", buf);
      }
      else  {
        printf("Blad funkcji accept.\n");
        printf("Kod bledu: %d\n", WSAGetLastError());
        system("PAUSE");
        return 1;
      }
    }
    else  {
      printf("Lipa ;/\n");
      break;
    }
  }
0

Pierwszy parametr select to musi być najwieksza wartosc deskryptora+1 a Ty dajesz 0 i to jest błąd.

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