Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Winsock - Reconnect

crafn [06.05.2007 15:35:09]

#

Oon tekemäs luokkaa joka helpottaa winsockin käyttöä. Oon tehny siihen semmosen funktion jonka pitäs aina yhdistää serveriin/clienttiin uudestaan, mikäli yhteys on katkennut.
Funktio yhdistää clientin aina uudestaan serveriin, mikäli serveri on sammunut. Ongelma onkin siinä miksi serverin ja clientin välille ei synny uutta yhteyttä jos clientin sammuttaa ja käynnistää uudestaan.

Winsocket.h

#ifndef WINSOCKET
#define WINSOCKET 1
#include <winsock2.h>
#include <windows.h>
#include <wininet.h>
#include <string>

class Winsocket { //luokka helpottamaan winsockin käyttöä
    private:
        bool yhteys; //ollaanko yhteydessä
        bool server; //ollaanko serveri vai clientti, oletuksena ollaan serveri
        u_short port; //portti jonne konnektaudutaan
        char ip[20]; //ip jonne konnektaudutaan jos ollaan clientti
        struct sockaddr_in service;
        DWORD AutoId;
        HANDLE HAuto;
    public:

        SOCKET Socket; //soketti

        bool Connection(); //palauttaa ollaanko yhteydessä

        bool ToClient(); //clientiksi
        bool ToServer(); //serveriksi
        bool IsServer(){ return server; }
        char* GetLocalIp(); //oman koneen ip

        bool InitSocket(); //alustaa soketin
        bool InitAll(); //alustaa kaiken

        bool SetIp(const char *Pip); //asettaa ip jonne konnektaudutaan
        bool SetPort(u_short Pport); //asettaa portin jonne konnektaudutaan
        u_short GetPort(); //palauttaa portin
        char* GetIp(); //palauttaa oman iipeen
        char* GetBuddysIp(); //palauttaa kaverin iipeen
        bool Connect(bool autoreconnect); //ottaa yhteydem
        bool Close(); //sulkee yhteyden kokonaan
        bool Disconnect(); //sulkee yhteyden
        bool Send(const char* data); //lähettää dataa
        bool GetData(char* data, int maxlength); //vastaanottaa dataa

        bool CleanAll(); //putsaa kaiken

        Winsocket(); //konstruktori
};
bool InitWinsock();
bool CleanWinsock();
DWORD WINAPI AutoReConnect(LPVOID lpParam); //autojoinaussäie
#endif

Winsocket.cpp

#include "winsocket.h"
#include <iostream>
using namespace std;
Winsocket::Winsocket(){ //konstruktori
    yhteys = false; //ei olla yhteydessä
    server = true; //ollaan serveri oletuksena
}
bool Winsocket::Connection(){
    return yhteys;
}
bool Winsocket::ToClient(){
    Close(); //suljetaan yhteys ettei lennossa mennä säätelemään asetuksia
    server = false; //clientiksi
    return false;
}
bool Winsocket::ToServer(){
    Close(); //suljetaan yhteys ettei lennossa mennä säätelemään asetuksia
    server = true; //serveriksi
    return false;
}

bool Winsocket::InitSocket(){
    Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //tehään soketti
    if(Socket == INVALID_SOCKET) {   //jos jokin meni pielee
        MessageBox(NULL, "Soketti ei alustu!", "Erhe!", 0);
        Disconnect(); //putsataa
        return true; //palautetaan erisuuri kuin 0
    }
    return false; //onnistuttiin
}
bool Winsocket::InitAll(){
    if(InitWinsock() == true && InitSocket() == true) return true;
    return false;
}
bool Winsocket::SetIp(const char *Pip){
    strcpy(ip, Pip);
    return false;
}
bool Winsocket::SetPort(u_short Pport){
    port = Pport;
    return false;
}

bool Winsocket::Connect(bool autoreconnect){

    if(server == true){
        service.sin_family = AF_INET;
        service.sin_port = htons(port);
        service.sin_addr.s_addr = INADDR_ANY;

        if (bind(Socket, (SOCKADDR*) &service,sizeof(service)) == SOCKET_ERROR){
            yhteys = false;
            Disconnect();
            cout << "Bindaus meni mönkään!" << WSAGetLastError() << "\n";
        }
        if (listen(Socket, 1 ) == SOCKET_ERROR ){
           yhteys = false;
           Disconnect();
           cout << "Kuuntelu meni mönkään!" << WSAGetLastError() << "\n";
        }
        else yhteys = true;
        SOCKET AcceptSocket;

        AcceptSocket = SOCKET_ERROR;
        while (AcceptSocket == SOCKET_ERROR){
            AcceptSocket = accept(Socket, NULL, NULL );
            if(yhteys == false)break;
        }

        Socket = AcceptSocket;
    }
    else {

        service.sin_family = AF_INET;
        service.sin_port = htons(port);
        service.sin_addr.s_addr = inet_addr(ip);

        if (connect(Socket, (SOCKADDR*) &service, sizeof(service)) == SOCKET_ERROR){
            cout << "Connecti meni mönkään! " << WSAGetLastError() << "\n";
            Disconnect();
            yhteys = false;
        }
        else {
            yhteys = true;
        }

    }
    if(autoreconnect) HAuto = CreateThread(0, 0, AutoReConnect, (LPVOID)this, 0, &AutoId);
    return !yhteys;
}
bool Winsocket::Close(){
    TerminateThread(HAuto, AutoId);
    closesocket(Socket);
    yhteys = false;
    return false;
}
bool Winsocket::Disconnect(){
    closesocket(Socket);
    yhteys = false;
    return false;
}
bool Winsocket::Send(const char* data){
    if(yhteys == true)send(Socket, data, strlen(data), 0);
    else {
        Disconnect();
        cout << "Ei yhteyttä, dataa ei voitu lähettää " << WSAGetLastError() << "\n";
        return true;
    }
    return false;
}
bool Winsocket::GetData(char* data, int maxlength){
    if(yhteys == true){
        int ret = recv(Socket, data, maxlength, 0);
        if(Socket == INVALID_SOCKET || ret == 0 || ret == -1){
            cout << "Data ei tullu " << WSAGetLastError() << " \n";
            data[0] = '\0';
            Disconnect();
            return true;
        }
    } else {
        cout << "Ei voitu vastaanottaa dataa, ei yhteyttä! " << WSAGetLastError() << "\n";
        Disconnect();
        return true;
    }
    return false;
}

/*ip-jutut poistettu*/

bool Winsocket::CleanAll(){
    Close();
    CleanWinsock();
    return false;
}
u_short Winsocket::GetPort(){
    return port;
}
char * Winsocket::GetIp(){
    return ip;
}
bool CleanWinsock(){
    WSACleanup();
    return false;
}
bool InitWinsock(){
    WSADATA Wsadata;
    if(WSAStartup( MAKEWORD(2,2), &Wsadata ) != NO_ERROR){ //tapahtui virhe
        cout << "Winsock ei alustunut! " << WSAGetLastError() << "\n";
        CleanWinsock();
        return true; //palautetaan erisuuri kuin 0 koska tapahtui virhe
    }
    return false; //palautetaan 0 koska onnistuttiin
}
DWORD WINAPI AutoReConnect(LPVOID lpParam){
    Winsocket *wsocket = (Winsocket*)lpParam;
    while(1){
        if(!InternetGetConnectedState(NULL, 0)){ //ollaanko netissä
            wsocket->Disconnect();
            Sleep(10);
        }
        if(wsocket->Connection() == false){
            if(wsocket->InitSocket() == true) cout << "autorekonnektin initsocket epäonnistu :(\n";
            if(!wsocket->Connect(false))cout << "jee rekonnekt toimii\n";
        }
        Sleep(1000);
    }
}

Server.cpp

#include <cstdlib>
#include <iostream>
#include <windows.h>
#include "winsocket.h"

using namespace std;

int main(int argc, char *argv[])
{
    char data[100] = "";
    InitWinsock();
    Winsocket* SSocket = new Winsocket;
    SSocket->SetPort(7576);
    SSocket->ToServer();
    SSocket->InitSocket();
    if(!SSocket->Connect(true))cout << "jee yhteys\n";
    while(1){
        if(SSocket->Connection()){
            SSocket->GetData(data, 100);
            cout << data << "\n";
            Sleep(1000);
            SSocket->Send("Terveiset serveriltä");
            Sleep(1000);
        }

        Sleep(10);
    }
    return EXIT_SUCCESS;
}

Client.cpp

#include <cstdlib>
#include <iostream>
#include <windows.h>
#include "winsocket.h"

using namespace std;

int main(int argc, char *argv[])
{
    char data[100] = "";
    InitWinsock();
    Winsocket* CSocket = new Winsocket;
    CSocket->SetPort(7576);
    CSocket->SetIp("91.152.182.144");
    CSocket->ToClient();
    CSocket->InitSocket();
    if(CSocket->Connect(true))cout << "jee yhteys\n";
    while(1){
        if(CSocket->Connection()){
            CSocket->Send("asd");
            Sleep(1000);
            CSocket->GetData(data, 100);
            cout << data << "\n";
            Sleep(1000);
        }
        Sleep(10);
    }

    return EXIT_SUCCESS;
}

Joo.. Toivottavasti joku nyt jaksaa lukea tän, ja auttaa..

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta