C 实现的 WebSocket 服务器握手失败

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C 实现的 WebSocket 服务器握手失败相关的知识,希望对你有一定的参考价值。

以下是处理WebSocket请求的代码
while (true)

app_sock = accept(listen_sock, (struct sockaddr *)&clientaddr, &socklen);
if (app_sock < 0)
printf("LOG_ERR: %s:%d, accept failed", __FILE__, __LINE__);
system("pause");
exit(1);

char IPdotdec[20] = 0 ;
inet_ntop(AF_INET, &clientaddr.sin_addr, IPdotdec, sizeof(IPdotdec));//将二进制整数转换为点分十进制
ntohs(clientaddr.sin_port);//将16位网络字节顺序转换为主机字节顺序
//receive data
recvlen = recv(app_sock, recvbuf, RECV_BUF_SIZE, 0);
if (recvlen < 0)

if (errno == EINTR)
recvlen = 0;
else
exit(1);

printf("receive data is \n: %s \n", recvbuf);

char *sendbuf = handshake(recvbuf, clientaddr, app_sock);
int ret = send(app_sock, sendbuf, strlen(sendbuf), 0);
//int ret = send(app_sock, sendbuf, strlen(sendbuf), 0);
if (ret == SOCKET_ERROR)
printf("send() failed len:%d:\n", strlen(sendbuf));

//printf("send() len:%d:\n", strlen(sendbuf));


closesocket(app_sock);


我不明白循环的closesocket()有没有影响,在调试的时候,如果注释掉closesocket()则send()无法发送出消息因为,在谷歌浏览器上看到客户端一直在等待直到到超时;如果加上closesocket()客户端能收到正确的头部,但是报错显示此时服务器已经关闭,这个问题困扰我很久了,希望各位前辈帮帮我

参考技术A WebSocket是html5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。在WebSocketAPI中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

Websocket握手失败404(golang服务器)

【中文标题】Websocket握手失败404(golang服务器)【英文标题】:Websocket handshake fails 404 (golang server) 【发布时间】:2016-02-04 13:32:56 【问题描述】:

我有一个简单的 go web 服务器,它在端口 localhost:8080 上提供一个公共文件夹,其中包含一个 html 文件以及一个带有 websocket 逻辑的客户端脚本。

在我的main.go file

listener, err := net.listen("tcp", "localhost:8080")
if err != nil 
    log.Fatal(err)

//full code in gist https://gist.github.com/Kielan/98706aaf5dc0be9d6fbe

然后在我的客户端脚本中

try 
    var sock = new WebSocket("ws://127.0.0.1:8080");
    console.log("Websocket - status: " + sock.readyState);

    sock.onopen = function(message) 
    console.log("CONNECTION opened..." + this.readyState);
    //onmessage, onerr, onclose, ect...

我在 chrome 中收到错误

WebSocket connection to 'ws://127.0.0.1:8080/' failed: Error during WebSocket handshake: Unexpected response code: 200

和火狐

Firefox can't establish a connection to the server at ws://127.0.0.1:8080/.

我发现 this article 指的是 node.js,表示将 /websocket 添加到我的客户端 websocket 字符串中,尽管它没有解决问题并导致 404

我认为响应代码 200 很好,我是否需要以某种方式将请求转换为 websocket,也许它默认为 http?如果是这样,我该怎么做?

【问题讨论】:

服务器端(或 http 服务器的任何部分)的 Web 套接字处理代码在哪里? @JimB 将要点添加到 main.go 文件,感谢您的反馈。 您的代码仅侦听 tcp 套接字。您根本没有 http 或 websocket 处理代码。 Websockets 是 HTTP/1.1 en.wikipedia.org/wiki/WebSocket 的一部分 【参考方案1】:

就像 JimB 指出的那样,您还没有处理 http 和 websocket 连接。

您可以使用 github.com/gorilla/websocket 包进行 websocket 处理 简单的设置如下所示:

package main

import (    
    "log"
    "net/http"
    "github.com/gorilla/websocket"
)

// wsHandler implements the Handler Interface
type wsHandler struct

func main() 
    router := http.NewServeMux()
    router.Handle("/", http.FileServer(http.Dir("./webroot"))) //handles static html / css etc. under ./webroot
    router.Handle("/ws", wsHandler) //handels websocket connections

    //serving
    log.Fatal(http.ListenAndServe("localhost:8080", router))


func (wsh wsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) 
    // upgrader is needed to upgrade the HTTP Connection to a websocket Connection
        upgrader := &websocket.Upgrader
            ReadBufferSize:  1024,
            WriteBufferSize: 1024,
        

        //Upgrading HTTP Connection to websocket connection
        wsConn, err := upgrader.Upgrade(w, r, nil)
        if err != nil 
            log.Printf("error upgrading %s", err)
            return
        

        //handle your websockets with wsConn

在您的 Javascript 中,您显然需要 var sock = new WebSocket("ws://localhost/ws:8080");

【讨论】:

感谢我在研究解决方案时意识到使用 gorilla 可能是最好的解决方案。我还要补充一点,这是 repo 中的一个很好的聊天示例。 github.com/gorilla/websocket/tree/master/examples/chat 如果你想看更多代码,你也可以看看我写的这个tic-tac-toe游戏服务器,它使用了gorilla包。 github.com/riscie/websocket-tic-tac-toe

以上是关于C 实现的 WebSocket 服务器握手失败的主要内容,如果未能解决你的问题,请参考以下文章

Websocket握手失败404(golang服务器)

WebSocket 连接失败。 WebSocket握手期间出错-socketjs

websocket失败:WebSocket握手期间出错:意外响应代码:400

使用 Maven,WebSocket 连接失败:WebSocket 握手期间出错:意外响应代码:404

失败:WebSocket 握手期间出错:“Sec-WebSocket-Accept”标头值不正确

tyrus websocket ssl 握手失败