Switching to websocket from simple Berkeley socket - sockets

I have a simple socket implementation which uses the standard low-level Berkeley socket functions (bind, listen, accept, read, etc).
This socket listens on a port, let's say X.
Now what I'm trying to achieve is to make Simple-WebSocket-Server to listen also on this port X.
Of course this is not possible by nature - I know.
My intention is this: In my simple socket implementation I would detect if the connected client (after accepting) is my client or a websocket one, then if I find the client to be a websocket one, I would pass the whole thing into this library to behave the same as like it was the one have accepted this client.
What would be good to hand over the socket's fd, along with a first bytes that my socket read before noticing a websocket request.
I'm a bit stuck on would be the best to do this, but I don't want to reimplement the whole websocket stuff for sure.

The tricky thing here is that the Simple-WebSocket-Server does its own accept, so I don't there is a way to had over to it a fd together with an array of "first bytes".
Some approaches I could think of:
modify the Simple-WebSocket-Server so that instead of closing a non-WS client or timing-out, it makes a call to your library
instead use something like websocketpp to create your own websocket server, and then select between the two servers (I did something similar for one of my own projects, where I had to detect the socket protocol from the first byte and then select an appropriate protocol handler wampcc protcol selector)
or, you could try to have the Simple-WebSocket-Server listen on a different port Y; you also listen on X, and if detect a web-socket client on X, you internally create an internal pair of queues and then open a connection to localhost:Y, and proceed to transfer bytes between the pair of sockets; this way you don't need to modify the Simple-WebSocket-Server code.

Related

How do I get useful data from a UDP socket using GNAT.Sockets in Ada?

Summary:
I am writing a server in Ada that should listen and reply to messages received over UDP. I am using the GNAT.Sockets library and have created a socket and bound it to a port. However, I am not sure how to listen for and receive messages on the socket. The Listen_Socket function is for TCP sockets and it seems that using Stream with UDP sockets is not recommended. I have seen the receive_socket and receive_vector procedures as alternatives, but I am not sure how to use them or how to convert the output to a usable format.
More details:
I am writing a server that should reply to messages that it gets over UDP. A minimal example of what I have so far would look like this:
with GNAT.Sockets;use GNAT.Sockets;
procedure udp is
sock: Socket_Type;
family: Family_Type:=Family_Inet;
port: Port_Type:=12345;
addr: Sock_Addr_Type(family);
begin
Create_Socket(sock,family,Socket_Datagram);
addr.Addr:=Any_Inet_Addr;
addr.Port:=port;
Bind_Socket(sock,addr);
-- Listen_Socket(sock); -- A TCP thing, not for UDP.
-- now what?
end UDP;
For a TCP socket, I can listen, accept, then use the Stream function to get a nice way to read the data (as in 'Read and 'Input). While the Stream function still exists, I have found an archive of a ten year old comp.lang.ada thread in which multiple people say not to use streams with UDP.
Looking in g-socket.ads, I do see alternatives: the receive_socket and receive_vector procedures. However, the output of the former is a Stream_Element_Array (with an offset indicating the length), and the latter has something similar, just with some kind of length associated with each Stream_Element.
According to https://stackoverflow.com/a/40045312/7105391, the way to change these types into a stream, is to not get them in the first place, and instead get a stream, which is not particularly helpful here.
Over at this github gist I found , Unchecked_Conversion is being used to turn the arrays into strings and vice versa, but given that the reference manual (13.13.1) says that type Stream_Element is mod <implementation-defined>;, I'm not entirely comfortable using that approach.
All in all, I'm pretty confused about how I'm supposed to do this. I'm even more confused about the lack of examples online, as this should be a pretty basic thing to do.

How to determine who wrote what to a socket, given 2 writers?

Say one part of a program writes some stuff to a socket and another part of the same program reads stuff from that same socket. If an external tool writes to that very same socket, how would I differentiate who wrote what to the socket (using the part that reads it)? Would using a named pipe work?
If you are talking about TCP the situation you describe is impossible, because connections are 1-to-1. If you mean UDP, you can get the sender address by setting the appropriate flags in the recvmesg() function.

Send a zero-data TCP/IP packet using Java

My goal is to send a TCP packet with empty data field, in order to test the socket with the remote machine.
I am using the OutputStream class's method of write(byte[] b).
my attempt:
outClient = ClientSocket.getOutputStream();
outClient.write(("").getBytes());
Doing so, the packet never show up on the wire. It works fine if "" is replaced by " " or any non-zero string.
I tried jpcap, which worked with me, but didn't serve my goal.
I thought of extending the OutputStream class, and implementing my own OutputStream.write method. But this is beyond my knowledge. Please give me advice if someone have already done such a thing.
If you just want to quickly detect silently dropped connections, you can use Socket.setKeepAlive( true ). This method ask TCP/IP to handle heartbeat probing without any data packets or application programming. If you want more control on the frequency of the heartbeat, however, you should implement heartbeat with application level packets.
See here for more details: http://mindprod.com/jgloss/socket.html#DISCONNECT
There is no such thing as an empty TCP packet, because there is no such thing as a TCP packet. TCP is a byte-stream protocol. If you send zero bytes, nothing happens.
To detect broken connections, short of keepalive which only helps you after two hours, you must rely on read timeouts and write exceptions.

Why the listen() function call is not needed when use UDP socket?

I'm just curious about this question, can any one tell me?
TCP is a streaming protocol between a server and clients. The protocol is reliable and requires separate state for each server<>client stream. The connect protocol, initiated with listen/accept, sets up this server<>client connection state. UDP is a connectionless, unreliable datagram, (message) protocol, so no need to listen for new connections - datagrams can come in in any order from any source.
It's because UDP is not connection oriented like TCP is, so there's no meaning in the listen/accept like there's for SOCK_STREAM. Try reading the paragraph "2.1. Two Types of Internet Sockets" in the Beej guide to network programming and the whole guide in general it is interesting.
If I remember it correctly, there is not any Listen() method associated with Udp, instead you call receive(), which is the same as Listen() when using TCP, both will block the process until it receive packages. hope this answers your question.
Considering the kernel source code, listen() is mainly used for initializing accept queue and syn queue, which are useless when using UDP.
The call chain is listen -> inet_listen -> inet_csk_listen_start -> reqsk_queue_alloc

TCP: is it possible to bind a socket and then /both/ connect from it and accept from it (both client and server rules)?

is it possible in any common platform - say, in Windows - to write a servient process that creates a socket, binds it to exactly one local "address:port" (fixed), and then:
use it to listen for incoming connections (on the specified port)
while at the same time
use it as a client socket to connect to some other servient (having source port identical to the one it exposes to others) ?
that is (sorry for the syntax abuse):
mySocket=socket(); mySocket.bind(myaddress, 3000);
mySocket.connectTo(neighbour, whateverport); // and present to others as port 3000
mySocket.listen(); // and it listens on 3000
mySocket.accept();
?
iirc, it's not even possible/advisable to try, even in the case an API wouldn't complain, but maybe it's me that is playing too much by the book... so I thought of asking you
thanks a lot!
No, a socket cannot be used for both listening and connecting at the same time. connect() will return a WSAEINVAL error if listen() was already called, and listen() will return a WSAEISCONN error if connect() was already called. You need to use separate sockets.
And if you could, there's be all kinds of troubles that crop up. For example, if select() returns that the socket is readable, do you do a recv() or an accept()? You want 2 sockets to play those two roles.
What advantage is there in one socket? For example, if you were hoping to do a blocking read until something interesting happens (incoming connection, incoming data), there are alternatives. In that example, you'd use select() to block on two sockets at once. The result from select() tells you which socket is ready. That tells you if you want to accept() a new connection from the one socket or recv() new data from the other socket.