none
Socket App problem RRS feed

  • Question

  • Well I'm sure there are other socket questions here but mine isn't general, it's specific. I'm rather confused as to why it doesn't work. What it's doin is telling me everyting is connecting wit no problems, but isn't actually making any connections on the client side. the server side, I'm not sure, I'm tryin to fix this one problem and hoping it will fix the other as well. it's returning a handle and everyting. but the server I set up recieves connections from other clients but not this one. the program I am programming the sockets for uses scripting as it is a game designer program. so what you'll see here in the code will usually return data to a calling script or set a boolean or the sort that the script can check to make the appropriate actions. eg Sockread and the such.

    Main.cpp

    /*case RECVSOCK_EVENT:
    switch(LOWORD(lParam))
    {
    case FD_ACCEPT:
    g_pSocket->m_Socket.Event[wParam].accept = true;
    WriteCheck("Connection Attempt");
    break;
    }
    break;*/

    /*case APPSOCK_EVENT:
    switch(LOWORD(lParam))
    {
    case FD_CONNECT:
    g_pSocket->m_Socket.Event[wParam].connect = true;
    break;
    case FD_READ:
    WriteCheck("Read attempt");
    g_pSocket->m_Socket.Event[wParam].read = true;
    break;
    case FD_WRITE:
    g_pSocket->m_Socket.Event[wParam].write = true;
    break;
    case FD_CLOSE:
    g_pSocket->m_Socket.Event[wParam].close = true;
    break;
    }*/


    I do realize that it's commented out. I'm not the most technical when it comes to debugging, but it works at times. this was when I decided to try the ASyncronousSocketEvent since the WSocketEventSelect wasn't working.... atleast I thought it didn't.

    This next one is the Socket class, very messy I know, I can only do what I can, no schooling on programmin, all was self taught.

    Socket.cpp

    //-----------------------------------------------------------------------------
    // File: Socket.cpp
    //
    // Desc: Handles networking
    //
    //-----------------------------------------------------------------------------
    #define STRICT

    #include "Socket.h"
    extern CSocket *g_pSocket;
    extern HWND g_hWnd;

    HRESULT AcquireNetwork(OZINFO socket, WSAPROTOCOL_INFO *protocol, ADDRINFO *address);
    int CALLBACK ConditionalAccept( LPWSABUF lpCallerId, LPWSABUF lpCallerData, LPQOS lpSQos, LPQOS lpGQos, LPWSABUF lpCalleeId, LPWSABUF lpCalleeData, GROUP FAR *Group, DWORD CallbackData);
    HRESULT CheckBanlist(OZ_SOCKET *Sock, SOCKADDR *Address);
    void CALLBACK CompleteSend(IN DWORD dwError, IN DWORD cbTransferred, IN LPWSAOVERLAPPED lpOverlapped, IN DWORD dwFlags);
    void ResetEvents(OZ_STATE *Event);

    //-----------------------------------------------------------------------------
    // Name: CSocket::CSocket()
    // Desc: Initializes CSocket Object
    //
    //-----------------------------------------------------------------------------
    CSocket::CSocket()
    {
    WriteCheck("CSocket::CSocket() - Initializing CSocket Object");
    port = "5001";
    host = "localhost";
    server = false;
    selection = 0;
    m_Socket.Sock = new SOCKET[1];
    m_Socket.Addr = new SOCKADDR[1];
    m_Socket.Event = new OZ_STATE[1];
    m_Socket.Login = new OZ_LOGIN[1];
    m_Socket.Max = 1;

    m_Socket.Sock[0] = INVALID_SOCKET;
    ResetEvents(&m_Socket.Event[0]);

    if(WSAStartup(0x202,&wsaData) == SOCKET_ERROR)
    {
    WriteCheck("CSocket::CSocket() - Socket Startup failed");
    WSACleanup();
    return;
    }
    }

    //-----------------------------------------------------------------------------
    // Name: CSocket::~CSocket()
    // Desc: Deletes CSocket Object
    //
    //-----------------------------------------------------------------------------
    CSocket::~CSocket()
    {
    WriteCheck("CSocket::~CSocket() - Deleting CSocket Object");

    WSACleanup();
    }

    //-----------------------------------------------------------------------------
    // Name: CSocket::SetSocket()
    // Desc: Changes all Socket info
    //
    //-----------------------------------------------------------------------------
    void CSocket::SetSocket(int param, char* val)
    {
    switch(param)
    {
    case PORT:
    port = val;
    break;
    case ADDRESS:
    host = val;
    break;
    case SOCKETS:
    // If it is the same value, this is a waste of time
    if(m_Socket.Max == atoi(val))
    break;
    //Cancel out all data first
    if(m_Socket.Max == 1)
    {
    if(m_Socket.Sock[0] != INVALID_SOCKET)
    {
    CloseSocket(0);
    }
    }
    else
    {
    for(int i = 0; i < (m_Socket.Max + 1); i++)
    {
    if(m_Socket.Sock[i] != INVALID_SOCKET)
    {
    CloseSocket(i);
    }
    }
    }

    // Delete old data
    SAFE_DELETE(m_Socket.Sock);
    SAFE_DELETE(m_Socket.Addr);
    SAFE_DELETE(m_Socket.Event);
    SAFE_DELETE(m_Socket.Login);

    // Create new data
    m_Socket.Sock = new SOCKET[atoi(val)];
    m_Socket.Addr = new SOCKADDR[atoi(val)];
    m_Socket.Login = new OZ_LOGIN[atoi(val)];
    m_Socket.Max = atoi(val);

    // Initialize new data
    if(m_Socket.Max == 1)
    {
    m_Socket.Event = new OZ_STATE[atoi(val)];
    m_Socket.Sock[0] = INVALID_SOCKET;
    ResetEvents(&m_Socket.Event[0]);
    ZeroMemory((char *)&m_Socket.ovr, sizeof(m_Socket.ovr));
    //m_Socket.ovr.hEvent = m_Socket.Event[1];
    }
    else
    {
    m_Socket.Event = new OZ_STATE[atoi(val)];
    for(int i = 0; i < (m_Socket.Max + 1); i++)
    {
    m_Socket.Sock[i] = INVALID_SOCKET;
    ResetEvents(&m_Socket.Event[i]);
    }
    }
    break;
    case MODE:
    if(!strcmp(val, "FALSE"))
    server = false;
    else if(!strcmp(val, "TRUE"))
    server = true;
    else
    // Do nothing, apparently they don't know how to spell
    break;
    case LOGIN:
    m_Socket.Login[selection].User = val;
    break;
    case PASSWORD:
    m_Socket.Login[selection].Password = val;
    break;
    }
    }

    //-----------------------------------------------------------------------------
    // Name: CSocket::ConnectSocket()
    // Desc: Connects us to the outside world
    //
    //-----------------------------------------------------------------------------
    int CSocket::ConnectSocket()
    {
    OZINFO info;
    info.socket = m_Socket.Max;
    info.host = host;
    info.port = port;
    int optval, nRet;
    long netEvents;

    // Acquire the Network info that we need
    AcquireNetwork(info, &protocol, &address);

    // Connect the socket
    m_Socket.Sock[0] = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
    &protocol, 0, NULL);

    // Check to see if there is more than 1 socket.
    if(m_Socket.Max > 1)
    {
    // Set the exclusive address option
    optval = 1;
    nRet = setsockopt(m_Socket.Sock[0], SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
    (char *)&optval, sizeof(optval));
    address.ai_addr = INADDR_ANY;

    // Bind it
    bind(m_Socket.Sock[0], (LPSOCKADDR)&address.ai_addr, sizeof(address.ai_addr));
    netEvents = FD_ACCEPT;
    nRet = WSAAsyncSelect(m_Socket.Sock[0], g_hWnd, RECVSOCK_EVENT, netEvents);
    }
    else
    {
    // Connect it
    WSAConnect(m_Socket.Sock[0], (LPSOCKADDR)&address.ai_addr, sizeof(address.ai_addr),NULL, NULL, NULL, NULL);
    if(m_Socket.Sock[0] == INVALID_SOCKET)
    WriteCheck("Socket Error!");
    netEvents = (FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE);
    nRet = WSAAsyncSelect(m_Socket.Sock[0], g_hWnd, APPSOCK_EVENT, netEvents);
    }
    switch(nRet) {
    case WSANOTINITIALISED:
    WriteCheck("Socket - Not Initialized");
    break;
    case WSAENETDOWN:
    WriteCheck("Socket - Network subsystem failure");
    break;
    case WSAEINVAL:
    WriteCheck("Socket - Invalid parameter");
    break;
    case WSAEINPROGRESS:
    WriteCheck("Socket - Blocking Call in Progress");
    break;
    case WSAENOTSOCK:
    WriteCheck("Socket - Invalid Socket");
    break;
    default:
    WriteCheck("Socket - Connected and ready for use.");
    break;
    }
    return m_Socket.Sock[0];
    }

    //-----------------------------------------------------------------------------
    // Name: CSocket::CloseSocket()
    // Desc: Closes a connection
    //
    //-----------------------------------------------------------------------------
    void CSocket::CloseSocket(int i)
    {
    // Remove Socket from banlist only and only if it's not banned
    OZ_BANLIST *bList;
    OZ_BANLIST *pList = NULL;
    bList = &m_Socket.BList;
    while(bList->Next != NULL)
    {
    if(bList->Address == m_Socket.Addr)
    {
    if(bList->Count < 3)
    pList->Next = bList->Next;
    WriteCheck("Socket - Address found, closing");
    }
    pList = bList;
    bList = (OZ_BANLIST *)pList->Next;
    }

    // close it and INVALIDATE the socket
    closesocket(m_Socket.Sock[i]);
    WriteCheck("Socket - Closed!");
    m_Socket.Sock[i] = INVALID_SOCKET;
    m_Socket.Connect--;
    }

    //-----------------------------------------------------------------------------
    // Name: CSocket::WriteSocket()
    // Desc: Writes out to the network
    //
    //-----------------------------------------------------------------------------
    void CSocket::WriteSocket(int i)
    {
    // I'm gonna make this as simple as possible and hope it works
    // Just send it and rely on the callback function to handle the rest
    DWORD nBytes = 0;
    selection = i;
    WriteCheck("Socket - Writing...");
    WSASend(m_Socket.Sock[i], &m_Socket.Data, 1, &nBytes, 0, NULL, NULL);
    }

    //-----------------------------------------------------------------------------
    // Name: CSocket::ReadSocket()
    // Desc: Reads incoming traffic
    //
    //-----------------------------------------------------------------------------
    void CSocket::ReadSocket(int i)
    {
    // Hope it works :/
    DWORD nBytes = 0;
    WriteCheck("Socket - Reading...");
    WSARecv(m_Socket.Sock[i], &m_Socket.Data, 1, &nBytes, 0, NULL, NULL);
    }

    //-----------------------------------------------------------------------------
    // Name: CSocket::CheckSocket()
    // Desc: Main Loop that handles Network events
    //
    //-----------------------------------------------------------------------------
    DWORD CSocket::CheckSocket()
    {
    // HaHa, the meat of the Socket object
    // I will require the Scripter to do all the calls so he/she will have to
    // ensure that they include this function in their script so they know
    // what's goin on, and handle everyting accordingly.
    // I want to provide full functionality to the user without all the mess
    // to go with it.

    // We need these
    /*DWORD Events;

    // Gets event info
    Events = WSAWaitForMultipleEvents((m_Socket.Max+1), m_Socket.Event, FALSE, 30, FALSE);
    switch(Events)
    {
    case WSA_WAIT_FAILED:
    case WAIT_IO_COMPLETION:
    case WSA_WAIT_TIMEOUT:
    break;

    default:
    m_Socket.NetworkEvents.lNetworkEvents = 0;
    WSAEnumNetworkEvents(m_Socket.Sock[Events], m_Socket.Event[Events], &m_Socket.NetworkEvents);
    if(FD_ACCEPT & m_Socket.NetworkEvents.lNetworkEvents)
    {
    WriteCheck("Socket - Connection requested");
    AcceptSocket();
    }
    return Events;
    }*/
    return false;
    }

    //-----------------------------------------------------------------------------
    // Name: CSocket::AcceptSocket()
    // Desc: Accepts an incoming connection, if and only if there is one open
    // Make sure you ask for enough connections before getting here >:O
    //-----------------------------------------------------------------------------
    int CSocket::AcceptSocket()
    {
    // Check the accept conditions to make sure this socket is acceptable
    SOCKET temp;
    WriteCheck("Socket - Accepting...");
    temp = WSAAccept(m_Socket.Sock[0], NULL, NULL, ConditionalAccept, (DWORD)&m_Socket);

    // if temp isn't invalid, then the accept was successful,
    // assign it to a socket
    if(temp != INVALID_SOCKET)
    {
    for(int i = 1; i <= (m_Socket.Max-1); i++)
    {
    if(m_Socket.Sock[i] == INVALID_SOCKET)
    {
    m_Socket.Sock[i] = temp;
    break;
    WriteCheck("Socket - Added to sockets.");
    }
    }
    WSAAsyncSelect(temp, g_hWnd, APPSOCK_EVENT, (FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE));
    return temp;
    }
    }

    //-----------------------------------------------------------------------------
    // Name: CSocket::ListenSocket()
    // Desc: Wait, you hear that :O Get the door, its Dominoes
    // NO! it's an incoming socket
    //-----------------------------------------------------------------------------
    int CSocket::ListenSocket()
    {
    return listen(m_Socket.Sock[0], SOMAXCONN);
    }

    //-----------------------------------------------------------------------------
    // Name: AcquireNetwork()
    // Desc: This initializes the network and prepares all sockets
    // NOTE: The scripter calling this, or the user that plays the quest
    // must make sure info is passed correctly prior to the calling of
    // this Function. Called by ListenSocket and ConnectSocket.
    //-----------------------------------------------------------------------------
    HRESULT AcquireNetwork(OZINFO socket, WSAPROTOCOL_INFO *protocol, ADDRINFO *address)
    {
    ADDRINFO hint;
    int nRet;
    WSAPROTOCOL_INFO *lpProtocolBuf = NULL;
    DWORD dwBufLen = 0;
    DWORD dwErr;

    // Setup hints to look for
    if(socket.socket > 0)
    hint.ai_flags = AI_PASSIVE;
    hint.ai_protocol = IPPROTO_TCP;
    hint.ai_family = AF_INET;
    hint.ai_socktype = SOCK_STREAM;

    // Now that we have our Hints, Fill Address info
    getaddrinfo(socket.host, socket.port, &hint, &address);
    //WriteCheckVal(address->ai_protocol);

    // Fill Protocol info
    nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen);
    lpProtocolBuf = (WSAPROTOCOL_INFO *)malloc(dwBufLen);
    nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen);

    for(int i = 0; i < nRet; i++)
    {
    if (AF_INET == lpProtocolBuf[i].iAddressFamily && IPPROTO_TCP == lpProtocolBuf[i].iProtocol)
    {
    *protocol = lpProtocolBuf[i];
    break;
    }
    }
    free(lpProtocolBuf);
    return true;
    }

    //-----------------------------------------------------------------------------
    // Name: ConditionalAccept()
    // Desc: A socket is only accepted when it meets these requirments
    //
    //-----------------------------------------------------------------------------
    int CALLBACK ConditionalAccept(
    LPWSABUF lpCallerId,
    LPWSABUF lpCallerData,
    LPQOS lpSQos,
    LPQOS lpGQos,
    LPWSABUF lpCalleeId,
    LPWSABUF lpCalleeData,
    GROUP FAR *Group,
    DWORD CallbackData
    )
    {
    int nRet = CF_ACCEPT;
    OZ_SOCKET *Sock = (OZ_SOCKET *)CallbackData;
    WriteCheck("Connection attempt");

    // Block banned addresses
    switch(CheckBanlist(Sock, (SOCKADDR *)lpCallerId->buf))
    {
    // Anti-DoS Attack
    case BANNED:
    case CONNECTED:
    nRet = CF_REJECT;
    return nRet;
    WriteCheck("Socket - Socket banned");
    break;
    case GOOD:
    break;
    }
    if(Sock->Connect == Sock->Max)
    return CF_REJECT;
    Sock->Connect++;
    WriteCheck("Socket - Accepted");
    return nRet;
    }

    //-----------------------------------------------------------------------------
    // Name: CheckBanlist()
    // Desc: This function checks a dynamic array of addresses to either ban or
    // reject multiple connections (Anti-DOS)
    //-----------------------------------------------------------------------------
    HRESULT CheckBanlist(OZ_SOCKET *Sock, SOCKADDR *Address)
    {
    // Loop through the BanList to see if we are here.
    OZ_BANLIST *bList;
    OZ_BANLIST *pList = NULL;
    OZ_BANLIST *tList = new OZ_BANLIST;
    bList = &Sock->BList;
    while(bList->Next != NULL)
    {
    if(bList->Address == Address)
    {
    if(bList->Count >= 3)
    return BANNED;
    bList->Count++;
    return CONNECTED;
    }
    if(bList->Next == NULL)
    break;
    pList = bList;
    bList = (OZ_BANLIST *)pList->Next;
    }
    bList->Address = Address;
    bList->Count++;
    bList->Next = (DWORD *)tList;
    Sock->CurSock = Address;
    return GOOD;
    }

    //-----------------------------------------------------------------------------
    // Name: CompleteSend()
    // Desc: This is the Send Complete Callback function returns when it was
    // sent successfully I hope
    //-----------------------------------------------------------------------------
    void CALLBACK CompleteSend(
    IN DWORD dwError,
    IN DWORD cbTransferred,
    IN LPWSAOVERLAPPED lpOverlapped,
    IN DWORD dwFlags
    )
    {
    g_pSocket->m_Socket.Data.len -= cbTransferred;
    g_pSocket->m_Socket.Data.buf += cbTransferred;
    if(g_pSocket->m_Socket.Data.len > 0)
    g_pSocket->WriteSocket(g_pSocket->selection);
    }

    //-----------------------------------------------------------------------------
    // Name: CSocket::ResetEvents()
    // Desc: Resets all states for the Event
    //
    //-----------------------------------------------------------------------------
    void ResetEvents(OZ_STATE *Event)
    {
    Event->accept = false;
    Event->close = false;
    Event->connect = false;
    Event->read = false;
    Event->write = false;
    }


    and the header file:

    Socket.h

    //-----------------------------------------------------------------------------
    // File: Socket.h
    //
    // Desc: Handles networking
    //
    //-----------------------------------------------------------------------------
    #ifndef CSOCKET_H
    #define CSOCKET_H

    #include <windowsx.h>
    #include "GeneralData.h"
    #include "CGame.h"
    #include <Winsock2.h>
    #include <ws2tcpip.h>

    //-----------------------------------------------------------------------------
    // Defines, constants, and global variables
    //-----------------------------------------------------------------------------

    // Socket msg
    #define RECVSOCK_EVENT (WM_APP + 100)
    #define APPSOCK_EVENT (WM_APP + 101)

    // Socket setting options
    #define PORT 0
    #define ADDRESS 1
    #define SOCKETS 2
    #define MODE 3
    #define LOGIN 4
    #define PASSWORD 5

    // Kouruu's Socket Error codes
    #define NO_ERROR 0
    #define NO_HOST 1
    #define NO_PORT 2
    #define NO_

    // Kouruu's Ban codes
    #define BANNED 2
    #define CONNECTED 1
    #define GOOD 0

    // structure for Login info for OZ
    typedef struct _OZ_LOGIN
    {
    char * User;
    char * Password;
    } OZ_LOGIN;

    // structure for Event states
    typedef struct _OZ_STATE
    {
    bool read;
    bool write;
    bool accept;
    bool connect;
    bool close;
    } OZ_STATE;

    // structure to handle the ban list
    typedef struct _OZ_BANLIST
    {
    SOCKADDR * Address; // List of addresses that made a login attempt
    int Count; // Increases if a connection is attempted while they are already connected 3 = DoS
    DWORD * Next; // Pointer place holder, if NULL last one on list; else, pointer to next structure
    } OZ_BANLIST;

    // structure to handle data transfer and socket info for OZ
    typedef struct _OZ_SOCKET
    {
    SOCKET * Sock;
    SOCKADDR * Addr;
    SOCKADDR * CurSock;
    WSAOVERLAPPED ovr;
    OZ_STATE * Event;
    OZ_LOGIN * Login;
    OZ_BANLIST BList;
    WSABUF Data;
    WSANETWORKEVENTS NetworkEvents;
    int Connect;
    int Max;
    } OZ_SOCKET;

    // structure to send to acquire network
    typedef struct _OZINFO
    {
    int socket;
    char* port;
    char* host;
    } OZINFO;

    //-----------------------------------------------------------------------------
    // Classes defined in this header file
    //-----------------------------------------------------------------------------
    class CSocket;

    //-----------------------------------------------------------------------------
    // Name: Class CSocket
    // Desc:
    //-----------------------------------------------------------------------------
    class CSocket
    {
    //Private Variables
    WSADATA wsaData;
    BOOL server;

    public:
    //Public Variables
    OZ_SOCKET m_Socket;
    char* port;
    char* host;
    WSAPROTOCOL_INFO protocol;
    ADDRINFO address;
    int selection;

    //Public Functions
    CSocket();
    ~CSocket();

    void SetSocket(int param, char* val);
    int ConnectSocket();
    void CloseSocket(int i);
    void WriteSocket(int i);
    void ReadSocket(int i);
    DWORD CheckSocket();
    int AcceptSocket();
    int ListenSocket();

    };
    #endif


    I dunno, I usually do alot of research on subjects I don't know about but this one happens to be the hardest one for me to research on and I had to break down and ask for help.

    Is there someting here I'm doing wrong? Someting that can cause it to tink it's connected but not actually connect? I really need help on this one. I can't move on wit my project til I tackle this problem.

    -----------------------------------------------------------------------------------------------
    Well, I've done some changes and was able to narrow it down. This really stumps me. I've located that connect returns SOCKET_ERROR. however I retrieve WSAGetLastError() and it returns 0. I'm not able to solve the issue if it's telling me this, I'm confused. Plez help if you have a suggestion what this is.
    Saturday, July 7, 2007 3:59 AM

All replies