I have a program that is running as a listener on a socket. From a javascript page I am able to send an open socket request using Websocket (ws://). My issue lies in that I can't seem to see the handshake or reply to it from the C program. I used wireshark to confirm that the javascript is sending the correct handshake but when I try to receive it in the buffer all I get are zeros.
In addition I was able to test the javascript on ws://echo.websocket.org so I am pretty sure it is working correctly. The error I get from the console in my web browser indicates that no reply was received to the handshake.
Edit: I know this is because I don't have a response set up.
My updated C program is as follows
#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;
}
Any direction would be super helpful. I am still very new to the world of C.
First of all, as pointed out by someone else, you should be using connfd in the recv() call:
recv(connfd, (char*)sendBuff, sizeof sendBuff, MSG_DONTWAIT);
If you have a telnet client available that can connect to your program, you should use that to experiment with your code. For example, if you are running on Linux, start your program in one terminal window and, from another terminal, type
telnet localhost 5000
Here is what happens when I do it:
## 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.
See what's happening? And this is not surprising: the code accepts a connection from the client, tries to read a message from the client without giving it a chance to send it, gets nothing (of course!), doesn't ever send anything back to the client, and closes the connection. Then it waits for the next connection.
Please read some tutorials on C socket programming, play with it, get it to work with a telnet client, and then move on to websockets.
It's a good start, anyway. Good luck!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With