Thread: Huge problems in Winsock recv!

  1. #1
    Registered User
    Join Date
    Sep 2003
    Posts
    27

    Huge problems in Winsock recv!

    Alright, I'm trying to use the OSCAR protocol to connect to AIM. I've never done any networking before, so I'm encountering lots of problems with Winsock.

    First, check out how a FLAP and a TLV are organized: http://iserverd1.khstu.ru/oscar/basic.html

    Then, here is the login sequence: http://iserverd1.khstu.ru/oscar/login.html

    Ok, so I set up a non-blocking socket like so:
    Code:
    Oscar::Oscar(HWND hwnd)
    {
    	m_window=hwnd;
    
    	m_dataLen = -1;
    
    	m_log=LogManager::getInstance();
    
        if(WSAStartup(MAKEWORD(1, 1), &m_wsaData))
    	{
    		int nret=WSAGetLastError();
    		m_log->Error(true, "Cannot startup Winsock!   #%i", nret);
    	}
    
        m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    	WSAAsyncSelect(m_socket, hwnd, WM_USER + 5, FD_CONNECT | FD_READ | FD_CLOSE);
    
        if (m_socket == INVALID_SOCKET)
        {
    		int nret=WSAGetLastError();
    		m_log->Error(true, "Socket creation failed!  #%i", nret);
        }
    }
    In my program that users the Oscar class:
    Code:
    LRESULT CALLBACK WindowsMsgHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	switch(msg)
    	{
    		case WM_USER + 5:
    			switch(WSAGETSELECTEVENT(lParam))
    			{
    				// we have data to read!
    				case FD_READ:
    					mainOscar->ReadSocket();
    					break;
    			}
    		break;
    ....
    And finally the ReadSocket command:
    Code:
    int Oscar::ReadSocket()
    {
    	// don't make more FD_READ messages
    	WSAAsyncSelect(m_socket, m_window, WM_USER+5, FD_CONNECT|FD_CLOSE);
    
    	char byteBuffer;
    	int ret;
    
    	if(m_currBuffer.size() == 0)
    	{
    		while((ret=recv(m_socket, &byteBuffer, 1, 0)) == 1)
    		{
    			if(byteBuffer == FLAP_DATA_BYTE)
    			{
    				m_currBuffer.push_back((BYTE)byteBuffer);
    				break;
    			}
    		}
    	}
    	// 1+1+2+2 = 6 bytes before data
    	if(m_currBuffer.size() < 6 && m_currBuffer.size() > 0)
    	{
    		int ret;
    		while(m_currBuffer.size() < 6)
    		{
    			if(recv(m_socket, &byteBuffer, 1, 0) != 1)
    				break;
    
    			m_currBuffer.push_back(*((BYTE*)&byteBuffer));
    		}
    	}
    
    	// cool, we have the whole header!  Now let's extract the data size!
    	if(m_currBuffer.size() == 6)
    	{
    		BYTE tempLen[2];
    		// do I need this endianness conversion??
    		tempLen[0]=m_currBuffer[5];
    		tempLen[1]=m_currBuffer[4];
    
    		m_dataLen=*((WORD*)tempLen);
    	}
    
    	// now we're recieving data
    	if(m_currBuffer.size() >= 6)
    	{
    		int ret;
    		// read while we have data and are still reading from the data
    		while(m_currBuffer.size() < m_dataLen+6)
    		{
    			if(recv(m_socket, &byteBuffer, 1, 0) != 1)
    			{
    				ret=WSAGetLastError();
    				if(ret == WSAEWOULDBLOCK)
    					Sleep(750);
    				break;
    			}
    
    			m_currBuffer.push_back(*((BYTE*)&byteBuffer));
    		}
    	}
    	
    	// we're all done reading!
    	if(m_currBuffer.size() == m_dataLen+6)
    	{
    		if(m_currBuffer[0] != FLAP_DATA_BYTE)
    		{
    			m_log->Error(false, "Recieved a packet not starting with the FLAP header!");
    			return -1;
    		}
    
    		m_log->Log(GREEN, "FLAP of size %i bytes recieved!", m_dataLen+6);
    		m_log->Flush();
    
    		// now we have a flap, so continue reading
    		FLAP *incoming=new FLAP();
    
    		// channel
    		incoming->channel=*((BYTE*)&m_currBuffer[1]);
    
    		// sequence num
    		incoming->sequenceNum=*((WORD*)&m_currBuffer[2]);
    
    		// now read in the data
    		for(int i=0; i < m_dataLen; ++i)
    		{
    			incoming->data.push_back(*((BYTE*)&m_currBuffer[6+i]));
    		}
    		m_dataLen=-1;
    		while(m_currBuffer.size())
    			m_currBuffer.pop_back();
    
    	// restore FD_READ messages
    	WSAAsyncSelect(m_socket, m_window, WM_USER+5, FD_READ|FD_CONNECT|FD_CLOSE);
    
    	return 0;
    }
    Ok, now let's talk about the problem. When I use my endianness thing up top, I get a data length of 4. There are simply no FLAPs (including the error FLAP) that are of size 4. Also, it is being sent on channel 1 when it should most definitely be sent on channel 4.

    Is there are endianness issue here, or something else at work?

    Thanks!

    P.S. I just logged the raw data I recieved and it looks like this (no endianness anythings, just in the order that it comes with line breaks seperating flap bit, flap header, flap data)

    2A
    01 BC D7 00 04
    00 00 00 01

    Also, note that I only read from 0 to length, so there may be more bits coming that I don't know about.
    Last edited by sirSolarius; 09-11-2004 at 09:54 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Winsock recv problems
    By cloudy in forum Windows Programming
    Replies: 2
    Last Post: 09-08-2006, 07:08 AM
  2. winsock problems
    By axr0284 in forum C++ Programming
    Replies: 5
    Last Post: 03-22-2006, 09:40 AM
  3. Winsock Problems
    By Zort in forum C++ Programming
    Replies: 11
    Last Post: 06-22-2005, 05:01 AM
  4. Winsock Messaging Program
    By Morgul in forum Windows Programming
    Replies: 13
    Last Post: 04-25-2005, 04:00 PM
  5. Winsock - Where do i start?
    By Brain Cell in forum Networking/Device Communication
    Replies: 5
    Last Post: 02-14-2005, 01:39 PM