Quantcast
Channel: Visual C forum
Viewing all articles
Browse latest Browse all 15302

How to establish a client websocket connection with winsock?

$
0
0

I have two functions for creating a socket and handshaking with a server:

BOOL websocket::create() 
{
	int att = 0;

	// Initialize Winsock
	WSADATA wsaData;
	res = WSAStartup(MAKEWORD(2,2), &wsaData);
	if (res != 0) {
		reportError(_T("websocket::create WSAStartup"), res);
		return FALSE;
	}

	// create sockaddr structure and initialize
	AddrInfo *result = NULL, *ptr = NULL, hints;
	SecureZeroMemory(&hints, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;

	// Resolve the server address and port
	res = GetAddrInfo(URL.server, URL.port, &hints, &result);
	if (res != 0) {
		reportError(_T("websocket::create GetAddrInfo"), res);
		WSACleanup();
		return FALSE;
	}

	// create a socket object
	webSocket = INVALID_SOCKET;

	// Attempt to connect to the first address returned by GetAddrInfo
	ptr = result;

	// Attempt to connect to an address until one succeeds
    for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {

		// Create a socket for connecting to the server
		webSocket = socket(ptr->ai_family, ptr->ai_socktype, 
						   ptr->ai_protocol);

		// Check if the socket is valid
		if (webSocket == INVALID_SOCKET) {
			reportError(_T("websocket::create socket()"), WSAGetLastError());
			FreeAddrInfo(result);
			WSACleanup();
			return FALSE;
		}

		// Connect to the server
        res = connect(webSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
        if (res == SOCKET_ERROR) {
            closesocket(webSocket);
            webSocket = INVALID_SOCKET;
			att++;
			reportStatus(_T("Attempt"), att);
            continue;
        }
        break;
    }

	FreeAddrInfo(result);

	if (webSocket == INVALID_SOCKET) {
		reportError(_T("websocket::create UNABLE TO CONNECT"), 0);
		WSACleanup();
		return FALSE;
	}


	return TRUE;
}

BOOL websocket::handShake()
{
	char  headerA[400];
	TCHAR headerW[400];

	// generate random value for the header
	TCHAR *tch = NULL;

	base64(&tch);

	if(tch == NULL) {
		reportError(_T("websocket::create pointer "), NULL);
		return FALSE;
	}

	_stprintf_s(headerW, 399, 
	_T("GET /%s%s HTTP/1.1\r\n")
	_T("Host: %s\r\n")
	_T("Upgrade: websocket\r\n")
	_T("Connection: keep-alive, Upgrade\r\n")
	_T("Sec-WebSocket-Key: %s\r\n")
	_T("Origin: http://%s\r\n")
	_T("Sec-WebSocket-Protocol: chat, superchat\r\n")
	_T("Sec-WebSocket-Version: 13")
	_T("\r\n\r\n"), 
	URL.path, URL.query, URL.server, tch, URL.server);

	delete [] tch;

	int size_needed = 
	WideCharToMultiByte(CP_ACP, 0, headerW, -1, NULL, 0, NULL, NULL);
    WideCharToMultiByte(CP_ACP, 0, headerW, -1, headerA, size_needed, NULL, NULL);
	
	// Send the header
    res = send(webSocket, headerA, (int)strlen(headerA), 0);
    if (res == SOCKET_ERROR) {
		reportError(_T("websocket::create send()"), WSAGetLastError());
        closesocket(webSocket);
        WSACleanup();
        return FALSE;
    }

	// Sending and receiving data
    char recvbuf[1025];
    int recvbuflen = 1025;

    // Receive until the peer closes the connection
    do {
        res = recv(webSocket, recvbuf, recvbuflen-1, 0);
        if (res > 0) {
			recvbuf[res] = '\0';
                        MessageBoxA(NULL, recvbuf, "Received", NULL);
		} else if (res == 0) {
            _stprintf_s(hlp, _T("Connection closed "));
			updateText(hlp);
		} else {
            reportError(_T("websocket::create receive()"), WSAGetLastError());
		}
    } while(res > 0);


    // cleanup
    closesocket(webSocket);
    WSACleanup();


	return TRUE;
}

Here is what I see in Wireshark:

I send this header to the server:

GET / HTTP/1.1
Host: echo.websocket.org
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: XbaSVjzMpuugjiIaTS1SYK8XDEE=
Origin: http://echo.websocket.org
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

then I get the response:

HTTP/1.1 101 Web Socket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Accept: 3FO+JS5IVEBEOLgEjiwoLSsQfAg=
Server: Kaazing Gateway
Date: Tue, 10 Sep 2013 03:33:01 GMT

and then I immediately get a message Websocket Connection Close [FIN].

So my general question is what am I doing wrong or missing here?

Am I somehow asking to close this connection?

I have a simple JavaScript test page that also sends a handshake and receives the same response using a built in Websocket class but then the connection stays alive and doesn't close until you initiate the closure.

Thank you!




Viewing all articles
Browse latest Browse all 15302

Trending Articles