ws://在C程序中

ws://在C程序中,c,sockets,C,Sockets,我有一个程序在套接字上作为侦听器运行。从javascript页面,我可以使用Websocket(ws://)发送一个开放套接字请求。我的问题在于,我似乎看不到C程序中的握手或回复。我使用wireshark来确认javascript是否发送了正确的握手,但当我尝试在缓冲区中接收握手时,得到的结果都是零 此外,我还能够在ws://echo.websocket.org上测试javascript,因此我非常确信它工作正常。我从web浏览器中的控制台收到的错误表明没有收到对握手的回复 编辑:我知道这是因为

我有一个程序在套接字上作为侦听器运行。从javascript页面,我可以使用Websocket(ws://)发送一个开放套接字请求。我的问题在于,我似乎看不到C程序中的握手或回复。我使用wireshark来确认javascript是否发送了正确的握手,但当我尝试在缓冲区中接收握手时,得到的结果都是零

此外,我还能够在ws://echo.websocket.org上测试javascript,因此我非常确信它工作正常。我从web浏览器中的控制台收到的错误表明没有收到对握手的回复

编辑:我知道这是因为我没有设置响应

我的更新的C程序如下

#include <sys/socket.h> //for socket
#include <netinet/in.h>
#include <arpa/inet.h> //inet_addr
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h> //strlen
#include <sys/types.h>

/* main function */
int main() {
    int listenfd = 0, connfd = 0;
    int status;
    struct sockaddr_in serv_addr;
    char revcBuff[1025];
    int dataPresent = 0;
    memset(&serv_addr, 0, sizeof(serv_addr)); //clear the memory for the server_addr
    memset(&revcBuff, 0, sizeof(revcBuff)); //clear the memory for the buffer
    serv_addr.sin_family = AF_INET; //specifiys that the address is IPv4
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);//gets the local address
    //serv_addr.sin_port = htons(13669); //gets the local port
    serv_addr.sin_port = htons(5000); //gets the local port

    //designate the socket
    listenfd = socket(AF_INET, SOCK_STREAM, 0); 
    if(listenfd < 0) {
        fprintf(stderr, "Socket creation failed due to: %s\n", strerror( errno )); //If the socket creation fails get the error
        return EXIT_FAILURE;
    }

    //binds to the local address and port to listen
    while ( (bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)))< 0) { 
        fprintf(stderr, "bind failed due to: %s\n Retrying.....\n", strerror( errno )); //If the bind fails get the error
        sleep(3); //time in seconds till next try
    } 

    //listen on socket
    if ( (listen(listenfd, 10))< 0) { 
       fprintf(stderr, "listen failed due to: %s\n", strerror( errno ));//If the listen fails get the error
        return EXIT_FAILURE;
    }

    //main program loop
    fprintf(stderr, "serverSock0-14 now running in listen mode \n");
    while (connfd >= 0) { //while socket is not in error mode try to accept incoming socket requests
        connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); //wait for an incoming socket request
        if ( connfd == -1) { //if atempted socket request failed 
            fprintf(stderr, "accept failed due to: %s\n", strerror( errno )); // if the accept fails
        }
        fprintf(stdout, "connection opened \n");
        while (dataPresent != -1) { //keep socket open till you receive a packet
            dataPresent = recv(connfd, &revcBuff, sizeof revcBuff, MSG_TRUNC); //receive data from buffer
            //dataPresent = recv(connfd, revcBuff, sizeof revcBuff, MSG_DONTWAIT); //receive data from buffer
            if ( dataPresent == -1) { //test if new data is bad
                fprintf(stderr, "Receive failed due to: %s\n", strerror( errno )); // if the accept fails
            } else if ( dataPresent == 0) { // if the socket is closed on the other end
                break; // Escape to the close socket statement
            } else {
                revcBuff[dataPresent] = '\0'; // null terminate the buffer
                fprintf(stdout, "Buff Hex unsigned: %x %x %x \n", (unsigned int) revcBuff[0], (unsigned int) revcBuff[1], (unsigned int) revcBuff[2]); 
                fprintf(stdout, "Buff Hex: %x %x %x %x %x \n", revcBuff[0], revcBuff[1], revcBuff[2], revcBuff[3], revcBuff[4], revcBuff[5]); 
                fprintf(stdout, "Buff: %s \nbytes received: %i \n", revcBuff, dataPresent); //Print out what you received
            }
            dataPresent = 0;
            usleep(7000);
        }
        if ((close(connfd))==0){//close the socket
            fprintf(stdout, "connection closed\n");
        }
    } //end main program loop
    return EXIT_SUCCESS;
}
#包含//用于套接字
#包括
#包括//inet\u addr
#包括
#包括
#包括
#包括
#包括//strlen
#包括
/*主要功能*/
int main(){
int listenfd=0,connfd=0;
智力状态;
服务地址中的结构sockaddr\u;
char revcBuff[1025];
int dataPresent=0;
memset(&serv_addr,0,sizeof(serv_addr));//清除服务器地址的内存
memset(&revcBuff,0,sizeof(revcBuff));//清除缓冲区的内存
serv\u addr.sin\u family=AF\u INET;//指定地址为IPv4
serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);//获取本地地址
//serv_addr.sin_port=htons(13669);//获取本地端口
serv_addr.sin_port=htons(5000);//获取本地端口
//指定插座
listenfd=套接字(AF_INET,SOCK_STREAM,0);
如果(列出的值小于0){
fprintf(stderr,“套接字创建失败,原因是:%s\n”,strerror(errno));//如果套接字创建失败,则获取错误信息
返回退出失败;
}
//绑定到要侦听的本地地址和端口
而((bind(listenfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr)))<0){
fprintf(stderr,“由于以下原因绑定失败:%s\n重试…\n”,strerror(errno));//如果绑定失败,则获取错误信息
sleep(3);//下次尝试前的时间(秒)
} 
//监听插座
如果((listenfd,10))<0{
fprintf(stderr,“由于:%s而侦听失败”,strerror(errno));//如果侦听失败,则获取错误
返回退出失败;
}
//主程序循环
fprintf(stderr,“serverSock0-14现在以侦听模式运行\n”);
当(connfd>=0){//当套接字未处于错误模式时,尝试接受传入的套接字请求
connfd=accept(listenfd,(struct sockaddr*)NULL,NULL);//等待传入的套接字请求
if(connfd==-1){//if-atempted套接字请求失败
fprintf(stderr,“由于:%s而接受失败”,strerror(errno));//如果接受失败
}
fprintf(标准输出,“连接已打开”);
while(dataPresent!=-1){//保持套接字打开,直到收到数据包
dataPresent=recv(connfd,&revcBuff,sizeof revcBuff,MSG_TRUNC);//从缓冲区接收数据
//dataPresent=recv(connfd,revcBuff,sizeof revcBuff,MSG_DONTWAIT);//从缓冲区接收数据
if(dataPresent==-1){//测试新数据是否错误
fprintf(stderr,“接收失败,原因:%s\n”,strerror(errno));//如果接受失败
}else if(dataPresent==0){//如果套接字在另一端关闭
break;//转义到closesocket语句
}否则{
revcBuff[dataPresent]='\0';//null终止缓冲区
fprintf(标准输出,“Buff十六进制无符号:%x%x%x\n”,(无符号整数)revcBuff[0],(无符号整数)revcBuff[1],(无符号整数)revcBuff[2]);
fprintf(标准输出,“Buff十六进制:%x%x%x%x%x\n”,revcBuff[0],revcBuff[1],revcBuff[2],revcBuff[3],revcBuff[4],revcBuff[5]);
fprintf(stdout,“Buff:%s\n收到的字节:%i\n”,revcBuff,dataPresent);//打印出收到的内容
}
dataPresent=0;
usleep(7000);
}
如果((close(connfd))==0{//关闭套接字
fprintf(标准输出,“连接关闭”\n);
}
}//结束主程序循环
返回退出成功;
}

任何方向都会非常有用。我对C的世界仍然很陌生。

首先,正如其他人指出的,您应该在
recv()调用中使用
connfd

recv(connfd, (char*)sendBuff, sizeof sendBuff, MSG_DONTWAIT);
如果你有一个
telnet
客户端可以连接到你的程序,你应该用它来测试你的代码。例如,如果您在Linux上运行,请在一个终端窗口中启动程序,然后从另一个终端键入

telnet本地主机5000
以下是我这样做时发生的情况:

##运行程序的终端(a.out):
美元/年
连接已打开
浅黄色:
连接关闭
连接已打开
浅黄色:
连接关闭
##我从以下位置连接的终端窗口:
$telnet本地主机5000
正在尝试127.0.0.1。。。
已连接到本地主机。
转义字符为“^]”。
连接被外部主机关闭。
$telnet本地主机5000
正在尝试127.0.0.1。。。
已连接到本地主机。
转义字符为“^]”。
连接被外部主机关闭。
看看发生了什么?这并不奇怪:代码接受来自客户机的连接,尝试从客户机读取消息而不给它发送消息的机会,什么也得不到(当然!),从不向客户机发送任何消息,然后关闭连接。然后等待下一个连接

请阅读一些关于C套接字编程的教程,使用它,让它与telnet客户端一起工作,然后转到WebSocket


无论如何,这是一个好的开始。祝你好运

> P>您可以考虑,而不是手动处理所有WebSoT细节,使用现有的HTTP服务器库。

特别是,是一个自由软件HTTP服务器库,它已经支持WebSocket。查看其文件

您需要一个C web