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!