Problemas con Sockets.

Iniciado por YagamiIori2002, 15 Diciembre 2011, 23:25 PM

0 Miembros y 1 Visitante están viendo este tema.

YagamiIori2002

holas como estan, bueno estoy tratando de realizar 2 progrmas un cliente y un servidor(Sockets), cuado mando datos de consola a consola de servidor y cliente funciona correctamente, pero intente hacer un programa el cliente en Win32 y el servidor en consola y no me funciona cargo los datos en un Dlg en el mensaje "WM_INITDIALOG:" cuando cargo los datos aqui y inmediatamente se conecta y manda un mensaje al el servidor, pero cuando quiero mandar los datos oprimiendo un boton no manda nada con send(Socket,buffers,strlen(buffers),0); el codigo es este: cliente-->

case WM_INITDIALOG:
      memset(&WsaDat,0,sizeof WsaDat);
      memset(&Socket,0,sizeof Socket);
      hListBox =  GetDlgItem(hDlg,IDC_EDIT1);


   WSAStartup(MAKEWORD(2,2),&WsaDat);
    Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
   
   host=gethostbyname("localhost");
   SOCKADDR_IN SockAddr;
   SockAddr.sin_port=htons(8888);
   SockAddr.sin_family=AF_INET;
   SockAddr.sin_addr.s_addr=*((unsigned long*)host->h_addr);
   
   connect(Socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr));
   Sleep(1000); <---si este sleep no lo hago no imprime en el server brf = cadena
   send(Socket,bfr,strlen(bfr),0);<---envia los datos pero solo con el sleep
   SetTimer(hDlg,IDC_TIMER,4000,NULL); <-este timer es para el ciclo infinito no pondre el codigo porque es lo mismo que lo del boton.

   
      return (INT_PTR)TRUE;

   case WM_COMMAND:

      switch(wParam)

      {
      case IDOK:
         char buffers[256];
         int test;
          test =sizeof(buffers);
         ZeroMemory(buffers,sizeof buffers);
   SendMessage(hListBox,WM_GETTEXT,255,LPARAM(buffers));<--tengo un Editcontro para mandar datos al server los recupero y envio
         send(Socket,buffers,strlen(buffers),0);<---no envia los datos
      }


bueno esa es la partes mas importantes del codigo funciona bien lo de inicio del Dlg pero al mandar informacion con el boton IDOK ya no manda nada no se a que se deba, ya llevo unos dias intentando pero ningun resoltado :rolleyes: se los agredeceria que me ayudaran.


         

BlackZeroX

#1
Los posibles problemas pueden estar en:

* send() que te retorna?...
* ¿Entra en el switch que esta dentro de case WM_COMMAND:?

Dulces Lunas!¡.
The Dark Shadow is my passion.

YagamiIori2002

#2
Si, todo esta bien incluso depuro el programa y entra en esa parte del codigo el send esta donde debe estar. yo digo que es la llamada a Socket, las variables las tengo globales.

BlackZeroX

#3
ok... mira debes de hacerlo ADECUADAMENTE, es decir, comprobando ERRORES lo que haces con sleep esta mal... NUNCA SUPONGAS que todo ira adecuadamente por arte de magia.

Te dejo una codigo de una clase que apenas estoy creando (llevo 1 dia apenas en ella) si ves horrores es por que aun la tengo en sucio... pero cumple perfectamente su funcion, te servira para que veas mas o menos tu proceso en que esta errado, le faltan algunos comentarios, pero se entiende bastante bien.



#ifndef CSocks_H
#define CSocks_H

//#include <mListLink.h>
#include <winsock2.h>
#include <iostream>
#include <queue>
#include <cstring>

using namespace std;

enum sckState{
    SCKCLOSED                   = 0,    /** Socket Cerrado completamente **/
    SCKOPEN                     = 1,    /** Socket actualmente Abierto **/
    SCKLISTENING                = 2,    /** Socket a la escucha de una conexion entrante **/
    SCKCONNECTIONPENDING        = 3,    /** Estado de conexxion pendiente del Socket **/
    SCKRESOLVINGHOST            = 4,    /** Se esta resolviendo los datos del equipo Host **/
    SCKHOSTRESOLVED             = 5,    /** Estado donde se indica que los Datos del otro Punto han sido completados **/
    SCKCONNECTING               = 6,    /** Se esta realizando una conexión **/
    SCKCONNECTED                = 7,    /** El Socket esta actualmente conectado **/
    SCKCLOSING                  = 8,    /** El Socket se esta cerrando actualmente **/
    SCKERROR                    = 9,    /** Estado que informa de un Error en el la clase **/
} SCKSTATES;

class CSockBase;
class CSockClient;
class CSockServer;

unsigned long getHostByNameAlias(const char* szDNS);
char* getLocalHostName();
char* getLocalHostIP();

void myCallSendData(CSockBase* t);
void myCallRequestData(CSockBase* t);
void myCallListen(CSockServer* t);


typedef struct Buffer { //: NODETREE {  // se usa en conjunto de mListLink.h
    char* szData;
    size_t size;
} BUFFER, *LPBUFFER;


typedef class CSockBase
{
    friend void myCallSendData(CSockBase* t);
    friend void myCallRequestData(CSockBase* t);
    public:
        CSockBase();
        virtual ~CSockBase();

        virtual void close();

        bool sendData(const char* szData, size_t size);
        size_t getData(const char* szData, size_t size);

        virtual unsigned short int getRemotePort();
        virtual string getRemoteHost();

        int getState();

        inline SOCKET getHandleSocket();
        inline HANDLE getTheardRequestData();
        inline HANDLE getTheardSendData();

        void (*pEventDataArrival) (CSockBase*);     /** Evento que se activa al haber una obtencion de datos desde el otro punto de la conexión **/
        void (*pEventClosed) (CSockBase*);          /** Evento que se activa al Cerrarse el Socket **/
        void (*pEventError) (CSockBase*);           /** Evento que se activa al haber un error del Socket **/
        void (*pEventConnect) (CSockBase*);         /** Evento que se activa al realizar una conexion **/
        void (*pEventSendComplete) (CSockBase*);         /** Evento que se activa al realizar una conexion **/

    protected:
        int iState;
        unsigned short int iPort;

        string sRemoteHost;
        SOCKET mySock;

        HANDLE hTheardRequestData;
        HANDLE hTheardSendData;

        WSADATA     tWSAData;/** Datos del componente del Sistema **/

        inline void setError();

        //LPBUFFER lpBuffer;
        queue<BUFFER> Buffer;

    private:
} CSOCKBASE, *LPCSOCKBASE;

string CSockBase::getRemoteHost()
{
    string sRet = "";
    return sRet;
}

SOCKET CSockBase::getHandleSocket()
{
    return this->mySock;
}

HANDLE CSockBase::getTheardRequestData()
{
    return this->hTheardRequestData;
}

HANDLE CSockBase::getTheardSendData()
{
    return this->hTheardSendData;
}

void CSockBase::setError()
{
    this->iState = SCKERROR;
    if (this->pEventError != NULL)   /* Evento */
        this->pEventError( this );
}

CSockBase::CSockBase()
{
    //this->pEventSendComplete = NULL;
    this->pEventSendComplete = NULL;
    this->pEventDataArrival = NULL;     /** Evento que se activa al haber una obtencion de datos desde el otro punto de la conexión **/
    this->pEventClosed = NULL;          /** Evento que se activa al Cerrarse el Socket **/
    this->pEventError = NULL;           /** Evento que se activa al haber un error del Socket **/
    this->pEventConnect = NULL;         /** Evento que se activa al realizar una conexion **/

    this->iState = SCKCLOSED;
    this->iPort = 0;
    this->mySock = INVALID_SOCKET;
    this->hTheardRequestData = NULL;
    this->hTheardSendData = NULL;

    if (WSAStartup(MAKEWORD(2,2), &this->tWSAData) == NO_ERROR)
    {
        this->iState = SCKCLOSED;
    } else {
        this->setError();
    }
}

CSockBase::~CSockBase()
{
    ::WSACleanup();
}

size_t CSockBase::getData(const char* szData, size_t size)
{
    return recv(this->mySock, (char*)szData, size, 0);
}

int CSockBase::getState()
{
    return this->iState;
}

bool CSockBase::sendData(const char* szData, size_t size)
{
    BUFFER NewPage;

    if (this->iState != SCKCONNECTED)
        return 0;

    if (size == 0 || szData == NULL)
        return 0;

    // Escribimos en la nueva pagina una copia de los datos.
    NewPage.szData = new char[size];
    NewPage.size = size;
    this->Buffer.push(NewPage);
    memcpy(NewPage.szData, szData, size);

    if (this->hTheardSendData != NULL)  //  Ya existe un Hilo enviando los datos?...
        return true;

    //Creamos el hilo para enviar los datos de este Socket.
    this->hTheardSendData = CreateThread(        // HANDLE WINAPI CreateThread(
                                NULL,               //__in_opt   LPSECURITY_ATTRIBUTES lpThreadAttributes,
                                0,                  //__in       SIZE_T dwStackSize,
                                (LPTHREAD_START_ROUTINE)myCallSendData,  //__in       LPTHREAD_START_ROUTINE lpStartAddress,
                                this,               //__in_opt   LPVOID lpParameter,
                                0,                  //__in       DWORD dwCreationFlags,
                                NULL                //__out_opt  LPDWORD lpThreadId
                                );
    if (this->hTheardSendData == NULL)
    {
        if (this->pEventError != NULL)   /* Evento */
            this->pEventError(this);
        this->setError();
        return false;
    }
    return true;
}

unsigned short int CSockBase::getRemotePort()
{
    return this->iPort;
}

void CSockBase::close()
{
    this->iState = SCKCLOSING;
    if (this->mySock != INVALID_SOCKET ) {
        closesocket(this->mySock);
        if (this->pEventClosed != NULL)
            this->pEventClosed(this);
    }
    this->mySock = INVALID_SOCKET;
    this->iState = SCKCLOSED;

    TerminateThread(this->hTheardRequestData,0);
    CloseHandle(this->hTheardRequestData);
    this->hTheardRequestData = NULL;

    TerminateThread(this->hTheardSendData,0);
    CloseHandle(this->hTheardSendData);
    this->hTheardSendData = NULL;
}



























typedef class CSockClient: public CSockBase
{
    public:
        CSockClient();
        virtual ~CSockClient() ;

        void close();
        bool connect(string sIP, unsigned short int port);

        string getRemoteHost();

        bool setRemotePort(unsigned short int port);
        bool setRemoteHost(string sIP);

    protected:
        sockaddr_in tSockAddrIn;
        HANDLE hTheardRequestConection;

    private:
} CSOCKCLIENT, *LPCSOCKCLIENT;

void CSockClient::close()
{
    this->iState = SCKCLOSING;
    if (this->mySock != INVALID_SOCKET ) {
        closesocket(this->mySock);
        if (this->pEventClosed != NULL)
            this->pEventClosed(this);
    }

    this->mySock = INVALID_SOCKET;

    TerminateThread(this->hTheardRequestData, 0);
    CloseHandle(this->hTheardRequestData);
    this->hTheardRequestData = NULL;

    TerminateThread(this->hTheardSendData,0);
    CloseHandle(this->hTheardSendData);
    this->hTheardSendData = NULL;

    this->iState = SCKCLOSED;
}

CSockClient::CSockClient() : CSockBase()
{
}

CSockClient::~CSockClient()
{
    this->close();
}

bool CSockClient::connect(string sIP, unsigned short int iPort)
{
    if (this->iState != SCKCLOSED )
    {
        this->setError();
        return false;
    }

    this->sRemoteHost.assign(sIP);
    this->iPort = iPort;

    memset(&this->tSockAddrIn, 0, sizeof(sockaddr_in));
    this->tSockAddrIn.sin_family = AF_INET;
    this->tSockAddrIn.sin_port = htons(this->iPort);

    this->iState = SCKOPEN;

    if (this->tSockAddrIn.sin_port == INVALID_SOCKET)
    {
        this->setError();
        return false;
    }

    this->tSockAddrIn.sin_addr.s_addr = getHostByNameAlias(this->sRemoteHost.c_str());

    if (this->tSockAddrIn.sin_addr.s_addr == INADDR_NONE)
    {
        this->setError();
        return false;
    }

    this->mySock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (this->mySock == INVALID_SOCKET)
    {
        this->setError();
        return false;
    }

    this->iState = SCKCONNECTING;

    if (::connect(this->mySock, (SOCKADDR*)&this->tSockAddrIn, sizeof(sockaddr_in)) == SOCKET_ERROR)
    {
        this->setError();
        return false;
    }

    //Creamos el hilo para resivir los datos de este Socket.
    this->hTheardRequestData = CreateThread(        // HANDLE WINAPI CreateThread(
                                NULL,               //__in_opt   LPSECURITY_ATTRIBUTES lpThreadAttributes,
                                0,                  //__in       SIZE_T dwStackSize,
                                (LPTHREAD_START_ROUTINE)myCallRequestData,  //__in       LPTHREAD_START_ROUTINE lpStartAddress,
                                this,               //__in_opt   LPVOID lpParameter,
                                0,                  //__in       DWORD dwCreationFlags,
                                NULL                //__out_opt  LPDWORD lpThreadId
                                );
    if (this->hTheardRequestData == NULL)
    {
        if (this->pEventError != NULL)   /* Evento */
            this->pEventError(this);

        if (this->mySock != INVALID_SOCKET )
            closesocket(this->mySock);

        this->mySock = INVALID_SOCKET;

        this->setError();

        return false;
    }

    this->iState = SCKCONNECTED;

    if (this->pEventConnect)
        this->pEventConnect(this);

    //Reistramos los eventos que deseamos obtener si es que hookeamos el Socket.
//    if (WSAAsyncSelect(this->mySock, NULL, 1025 ,FD_READ | FD_CONNECT | FD_CLOSE) != SOCKET_ERROR)
//        return true;

    return true;
}

bool CSockClient::setRemotePort(unsigned short int iPort)
{
    if (this->iState != SCKCLOSED)
    {
        if (this->pEventError != NULL)   /* Evento de Error */
            this->pEventError(this);
        return false;
    }
    this->iPort = iPort;
    return true;
}

bool CSockClient::setRemoteHost(string sIP)
{
    if (this->iState != SCKCLOSED)
    {
        if (this->pEventError != NULL)   /* Evento de Error */
            this->pEventError(this);
        return false;
    }
    this->sRemoteHost.assign(sIP);
    return true;
}

string CSockClient::getRemoteHost()
{
    return this->sRemoteHost;
}






















typedef class CSockServer: public CSockBase
{
    public:

        CSockServer();
/*        virtual ~CSockServer() ;

        void close();
        bool listen(unsigned short int port);
        bool listen();

        string getRemoteHost();

        bool setRemotePort(unsigned short int port);
        bool setRemoteHost(string sIP);
*/
        inline HANDLE getTheardRequestConection();
        void (*pEventRequestConection) (CSockBase*);/** Evento que se activa al haber una peticion de conexión **/

    protected:
        sockaddr_in tSockAddrIn;
        HANDLE hTheardRequestConection;

    private:
} CSOCKSERVER, *LPCSOCKSERVER;

CSockServer::CSockServer() : CSockBase()
{
    this->pEventRequestConection;
    this->hTheardRequestConection = NULL;
}

HANDLE CSockServer::getTheardRequestConection()
{
    return this->hTheardRequestConection;
}








void myCallSendData(CSockBase* t)
/**
CallBack de SendData...
Envia las paginas de Datos en el orden adecuado.
CSockBase t = Clase del Socket
**/
{
    BUFFER page;
    while (!t->Buffer.empty()) {
        page = t->Buffer.front();
        send(t->mySock, page.szData, page.size, 0);
        delete page.szData;
        t->Buffer.pop();
        if (t->pEventSendComplete)
            t->pEventSendComplete(t);
    }
    t->hTheardSendData = NULL;
}

/*** CallBack RequestData ***/
void myCallRequestData(CSockBase* t)
{
    do {
        if (recv(t->mySock, NULL, 0, 0) == INVALID_SOCKET)
            t->close(); //  Cerramos si se desconecto el Socket (Se termina automaticamente este hilo al invocar a t->close()).
        if (t->pEventDataArrival != NULL)
            t->pEventDataArrival(t);
    } while(1);
}

/*** CallBack Listen Server ***/
void myCallListen(CSockServer* t)
{
//    accept(t->getHandleSocket(), )
}

unsigned long getHostByNameAlias(const char *szDNS)
{
    unsigned long   uiRet;
    hostent         *hHost = NULL;

    uiRet = inet_addr(szDNS);
    if (uiRet != INADDR_NONE )
        return uiRet;

    /* Obtenemos la "net_addr" de otra manera */
    hHost = gethostbyname(szDNS);
    if (hHost != NULL)
    {
        if (hHost->h_length > 0)
            memcpy(&uiRet, hHost->h_addr_list[0], sizeof(unsigned long) );
    }
    return uiRet;
}

char* getLocalHostName()
{
    char* szRet = new char[MAX_PATH];
    if (gethostname(szRet, MAX_PATH) == SOCKET_ERROR)
    {
        delete szRet;
        return NULL;
    }
    return szRet;
}

char* getLocalHostIP()
{
    hostent *hHost;
    in_addr addr;
    char    *p;

    p = getLocalHostName();
    hHost = gethostbyname((const char*)p);
    delete p;

    if (hHost->h_addrtype == AF_INET)
    {
        if (hHost->h_addr_list[0] > 0)
        {
            addr.s_addr = *(u_long*)hHost->h_addr_list[0];
            return inet_ntoa(addr);
        }
    }
    return NULL;
}

#endif // CSocks_H



Las clases se usan de la siguiente manera... obviamente CSockServer aun no esta hecha como se ve en el codigo anterior...

Código (cpp) [Seleccionar]


#include <iostream>
#include <include/CSocks.h>

#define MAXCLIENTS 1
#define MAXFOR 1

using namespace std;

void myEventConnect(LPCSOCKBASE t)
{
    char szEnter[3] = "";
    string sBuff = "GET / HTTP/1.1";
    int i = 0;
    szEnter[0] = (char)10;
    szEnter[1] = (char)13;
    sBuff.append(szEnter); //  Salto de Linea
    sBuff.append("Host: www.google.com.mx");
    sBuff.append(szEnter); //  Salto de Linea
    sBuff.append("User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:8.0) Gecko/20100101 Firefox/8.0");
    sBuff.append(szEnter); //  Salto de Linea
    sBuff.append("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
    sBuff.append(szEnter); //  Salto de Linea
    sBuff.append("Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3");
    sBuff.append(szEnter); //  Salto de Linea
    sBuff.append("Accept-Encoding: gzip, deflate");
    sBuff.append(szEnter); //  Salto de Linea
    sBuff.append("Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7");
    sBuff.append(szEnter); //  Salto de Linea
    sBuff.append("Connection: keep-alive");
    sBuff.append(szEnter); //  Salto de Linea
    sBuff.append(szEnter); //  Salto de Linea

    cout << "Conectado a " << ((CSockClient*)t)->getRemoteHost() << endl;
    cout << "Se empesara a enviar mensajes a lo BRUTO!¡." << endl;
    for (i = 0; i < MAXFOR; i++)
        if ( ((CSockClient*)t)->sendData(sBuff.data(), sBuff.length()))
            cout << "Enviado Correctamente." << endl;
    cout << endl << endl << endl << endl;
}

void myEventDataArrival(LPCSOCKBASE t)
{
    char szBuff[MAX_PATH] = {};
    size_t size = 0;
    size = t->getData((const char*)szBuff, MAX_PATH);
    cout << "Bytes Recividos: " << (int)size << " Bytes" << endl;
    cout << "Data: " << szBuff << endl;
}

void myEventError(LPCSOCKBASE t)
{
    cout << "Error del Socket" << endl;
    cout << endl << endl << endl << endl;
}

void myEventClosed(LPCSOCKBASE t)
{
    cout << "Socket Cerrado" << endl;
    cout << endl << endl << endl << endl;
    //delete (LPCSOCKCLIENT)t;    //  No recomendado.
}

int main()
{
    LPCSOCKCLIENT myClient[MAXCLIENTS];
    int i = 0;

    for (i = 0; i < MAXCLIENTS; i++)
        myClient[i] = new CSOCKCLIENT;

    for (i = 0; i < MAXCLIENTS; i++) {
        myClient[i]->pEventConnect = myEventConnect;
        myClient[i]->pEventDataArrival = myEventDataArrival;
        myClient[i]->pEventError = myEventError;
        myClient[i]->pEventClosed = myEventClosed;
        myClient[i]->connect("www.google.com.mx", 80);
    }

    cout << "Estos Son los Hilos encargados de los procesos de los Sockets..." << endl;

    for (i = 0; i < MAXCLIENTS; i++)
        cout << "myClient[" << i << "]\tRequestData: " << myClient[i]->getTheardRequestData() << "\tSendData: " << myClient[i]->getTheardSendData() << endl;

    cout << endl << endl << endl << endl;

    cin.get();

    for (i = 0; i < MAXCLIENTS; i++)
        cout << "myClient[" << i << "]\tRequestData: " << myClient[i]->getTheardRequestData() << "\tSendData: " << myClient[i]->getTheardSendData() << endl;

    cin.get();

    for (i = 0; i < MAXCLIENTS; i++) {
        myClient[i]->close();
        cout << "myClient[" << i << "]\tRequestData: " << myClient[i]->getTheardRequestData() << "\tSendData: " << myClient[i]->getTheardSendData() << endl;
    }

    cin.get();

    for (i = 0; i < MAXCLIENTS; i++)
        delete myClient[i];

    return EXIT_SUCCESS;
}



Dulces Lunas!¡.
The Dark Shadow is my passion.

YagamiIori2002

Perdon por la tardanza, pues tu codigo es muy largo le entiendo un poco :rolleyes: apenas estoy empezando en la progrmacion de sockets. nesecito un poco mas de conocimientos seguire intentando solucionar mi error y tomare en cuenta este codigo para estudiarlo, gracias.