2015-12-16 3 views
3

У меня есть программа, которая работает как слушатель в сокете. На странице javascript я могу отправить открытый запрос сокета с помощью Websocket (ws: //). Моя проблема заключается в том, что я не могу видеть рукопожатие или отвечать на него по программе C. Я использовал wirehark, чтобы подтвердить, что javascript отправляет правильное рукопожатие, но когда я пытаюсь получить его в буфере, все, что я получаю, это нули.ws: // в программе C

Кроме того, я смог проверить javascript на ws: //echo.websocket.org, поэтому я уверен, что он работает правильно. Ошибка, которую я получаю с консоли в своем веб-браузере, указывает, что в рукопожатие не было получено ответа.

Редактировать: Я знаю, это потому, что у меня нет ответа.

Мой обновляется программа 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; 
} 

Любое направление было бы супер полезно. Я все еще очень новый мир C.

+1

Вам нужна библиотека веб-раскладок C. –

+1

Не должно ли memset() использовать 0 вместо «0» (что равно 48)? – Jens

+0

Весь memset() - это культовое программирование. вместо этого следует использовать return from recv(). (и: зачем кому-то использовать RAW-сокет для такого рода тривиальных вещей?) – wildplasser

ответ

3

Прежде всего, как отметил кто-то еще, вы должны использовать connfd в recv() вызова:

recv(connfd, (char*)sendBuff, sizeof sendBuff, MSG_DONTWAIT); 

Если у вас имеется клиент telnet который может подключиться к вашей программе, вы должны использовать это, чтобы поэкспериментировать с вашим кодом. Например, если вы работаете на Linux, запустите программу в одном окне терминала и от другого терминала, типа

telnet localhost 5000 

Вот что происходит, когда я это делаю:

## The terminal where I run the program (a.out): 
$ ./a.out 
connection opened 
Buff: 
connection closed 
connection opened 
Buff: 
connection closed 

## The terminal window I connect from: 

$ telnet localhost 5000 
Trying 127.0.0.1... 
Connected to localhost. 
Escape character is '^]'. 
Connection closed by foreign host. 
$ telnet localhost 5000 
Trying 127.0.0.1... 
Connected to localhost. 
Escape character is '^]'. 
Connection closed by foreign host. 

Посмотрите, что происходит? И это неудивительно: код принимает соединение с клиентом, пытается прочитать сообщение от клиента, не давая ему возможность отправить его, ничего не получает (конечно!), Никогда ничего не посылает клиенту , и закрывает соединение. Затем он ждет следующего соединения.

Прочтите несколько руководств по программированию на сокетах C, поиграйте с ним, попросите его работать с клиентом telnet, а затем перейдите к веб-окнам.

Это хорошее начало, во всяком случае. Удачи!

+0

Хорошо поймать на connfd. Я забыл обновить это в вопросе. Я буду играть с тем, чтобы telnet работал в дополнение к моему чтению в libwebsockets. – mando222

0

Возможно, вместо ручной обработки всех сведений о веб-узле вы можете использовать некоторую существующую библиотеку HTTP-сервера.

В частности, libonion является бесплатной программой HTTP-серверной библиотеки и уже поддерживает веб-узлы. См. Его файл examples/websockets/websockets.c

Смежные вопросы