Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Problem z Winsock

Ostatnio zmodyfikowano 2011-03-24 16:37
Autor Wiadomość
piotrwalkusz1
Temat założony przez niniejszego użytkownika
Problem z Winsock
» 2011-03-23 21:00:34
Witam!
Niedawno zaczołem programować w gniazdach, ale od samego początku napotykam trudności. Z tym problemem nie mogę sobie poradzić. Oto kod serwera (dla ułatwienia dodałem mnóstwo 'cout') :
 
C/C++
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <conio.h>
#include <iostream>
#include <vector>

using namespace std;

class klijent
{
public:
    struct sockaddr_in adres;
    SOCKET gniazdo;
    int id;
    string nazwa;
};

void wyzeruj_sety( fd_set * slu, fd_set * wys, vector < klijent > & k );

int main( int argc, char * argv[] )
{
    WORD RequiredVersion;
    WSADATA WData;
    SOCKET ss, s;
    struct sockaddr_in addr, incom;
    long val;
    klijent kli;
    vector < klijent > klijenci;
    fd_set slu, wys;
    char buff[ 100 ];
    int licznik_id = 1;
   
    RequiredVersion = MAKEWORD( 2, 0 );
   
    if( WSAStartup( RequiredVersion, & WData ) != 0 ) {
        printf( "Blad inicjalizacji WinSock2\n" );
        getch();
        return 1;
    }
   
    memset(( void * ) & addr, 0, sizeof( addr ) );
    addr.sin_family = AF_INET;
    addr.sin_port = htons( 10000 );
    addr.sin_addr.s_addr = INADDR_ANY;
    cout << "Inicjalizacja wlasnego adresu\n";
   
    ss = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
    cout << "Inicjalizacja socketa ss\n";
    bind( ss,( struct sockaddr * ) & addr, sizeof( addr ) );
    listen( ss, 10 );
    cout << "Nasluchiwanie na socku ss\n";
    int licznik = 0;
    int alen = sizeof( klijenci[ 0 ].adres );
   
    while( 1 )
    {
        cout << "Poczatek petli\n";
        wyzeruj_sety( & slu, & wys, klijenci );
        cout << "Wyzerowanie setow\n";
        FD_SET( ss, & slu );
        cout << "Dodanie socka ss do deskryptorow gniazd nasluchujacych\n";
        cout << "Wyszukiwanie aktywnych deskryptorow\n";
        if( select( 0, & slu, & wys, NULL, NULL ) != SOCKET_ERROR )
        {
            cout << "Funkcja select\n";
            for( int i = 0; i < klijenci.size(); i++ )
            {
                cout << "Petla for" << endl <<
                "i = " << i << endl;
                if( FD_ISSET( klijenci[ i ].gniazdo, & slu ) )
                {
                    cout << "*****To gniazdo otrzymalo wiadomosc\n";
                    int a = recv( klijenci[ i ].gniazdo, buff, 100, 0 );
                    if( a == 0 || a == SOCKET_ERROR )
                    {
                        cout << "Brak wiadomosci\n";
                    }
                }
            }
            cout << "-----Sprawdzenie czy ktos chce sie polaczyc\n";
            if( FD_ISSET( ss, & slu ) )
            {
                cout << "Ktos sie polaczyl\n";
                cout << "Akceptowanie\n";
                s = accept( ss,( sockaddr * ) & incom,( int * ) sizeof( incom ) );
                if( s != INVALID_SOCKET )
                {
                    kli.gniazdo = s;
                    kli.id = licznik_id++;
                    kli.adres = incom;
                    klijenci.push_back( kli );
                    cout << "Nowa osoba o id : " << licznik_id - 1 << endl;
                }
            }
        }
    }
    for( int i = 0; i < klijenci.size(); i++ )
         closesocket( klijenci[ i ].gniazdo );
   
    closesocket( ss );
   
    WSACleanup();
    return 0;
}

void wyzeruj_sety( fd_set * slu, fd_set * wys, vector < klijent > & k )
{
    FD_ZERO( slu );
    FD_ZERO( wys );
    cout << "Trwa zerowanie setow\n";
    cout << "k.size() = " << k.size() << endl;
    for( int i = 0; i != k.size(); i++ )
    {
        cout << "Zerowanie dla klijenta " << i << endl;
        if( k[ i ].gniazdo != 0 )
        {
            cout << "-Czyszczenie\n";
            FD_SET( k[ i ].gniazdo, slu );
            FD_SET( k[ i ].gniazdo, wys );
        }
        else
             cout << "-Usuwanie\n";
       
        k.erase( k.begin() + 0 );
        i--;
    }
}

Przy uruchomieniu serwera pojawiają się wszystkie komentarze wyświetlane strumieniem cout. Dopiero jak
połączymy się z klientem program mnie zaskakuje. Nie pojawił się napis "Nowa osoba o id : 1". Proszę o poprawienie mojego kodu.
P-29619
DejaVu
» 2011-03-23 21:03:08
Kursy
Kurs WinSock, C++Beej's Guide to Network Programming - Używanie gniazd internetowych. (kurs)
P-29620
yoogi
» 2011-03-23 23:29:48
Witam, szczerze mówiąc mi przykłady z tego kursu nie chciały się kompilować, bo nie miałem dużo bibliotek, osobiście polecam:
http://warsztat.gd/articles.php?x=view&id=274
ja z tego nic nie rozumiałem ale jak pobrałem sobie przykłady, skompilowałem, zobaczyłem jak działa to od razu coś mi do głowy weszło :)
Ja sobie to tłumaczyłem tak:
są 2 główne funkcję program, a właściwie recv() i send() funkcja recv odbiera dane do jakiejś zmiennej, a send je wysyła. Reszta to same inicjację biblioteki czyli ustawienia na jakim porcie działa, na jaki adres ma wysyłać dane i sprawdzanie czy na pewno wszystkie operację się powiodły.

Mam nadzieję że to przemówienie ci pomoże :)
P-29621
piotrwalkusz1
Temat założony przez niniejszego użytkownika
» 2011-03-24 16:37:24
Mnie tak samo nie chciały się kompilować te przykłady, bo zostały stworzone do Unixa. Popróbuje na warsztatach. Dzięki. A gdy ktoś mógł w tym czasie poprawić mój źle działający program to byłbym wdzięczny.

//edit : Naprawiłem już program. Miałem kilka błędów. Dzięki za pomoc.
P-29651
« 1 »
  Strona 1 z 1