net-listen and sockets

Started by DrDave, September 01, 2008, 01:00:29 AM

Previous topic - Next topic

DrDave

I needed to do some research on TCP and UDP connections. I was going through the relevant functions in newLISP and found (net-listen) with this description
QuoteA call to net-listen returns immediately with a socket number, which is then used by the blocking net-accept function to wait for a connection. As soon as a connection is accepted, net-accept returns a socket number that can be used to communicate with the connecting client.


There seems to be a small but significant conflict here. "... net-listen returns immediately with a socket number" versus "As soon as a connection is accepted [by net-accept], net-accept returns a socket number...")



On the face of it, this description has (net-listen) first returning a socket number when it begins listening, and then (net-accept) returning a socket number when a connection is established. How can both functions return a socket number? And if both do, why does (net-listen) return one at all?



I did a little  testing in termianl mode and found that indeed (net-listen 2000) returned immediatley with the integer 112. But in my literature research I found that if a diagnostics tool is run to check for the IP address and port of the server or remote client, then *until* a connection is established, the most common result is to display IP 0.0.0.0 and port 0. So I ran (net-local 112) and it retuned ("0.0.0.0" 2000).



And further, I found that *until* a connection is established, the socket number does not exist, because the socket number is the mapping to the connection details of the server and client. So, if no connection, nothing to map, so no socket number is generated. So (net-accept) is where the real socket number should be created.



If this is correct, then the first part of the quotation above, "... net-listen returns immediately with a socket number", cannot be correct. At best , it would return with a *potential* socket number, or an intermediate pseudo-socket number, or whatever. So what in reality is it that (net-listen) is returning?



I also then ran (net-peer 112), expecting to see ("0.0.0.0" 0) returned. But instead, it returned ("" 0).
...it is better to first strive for clarity and correctness and to make programs efficient only if really needed.

\"Getting Started with Erlang\"  version 5.6.2

DrDave

#1
After more research, I am able to answer how this apparent inconsistency can be resolved:
Quote from: "DrDave"
On the face of it, this description has (net-listen) first returning a socket number when it begins listening, and then (net-accept) returning a socket number when a connection is established. How can both functions return a socket number? And if both do, why does (net-listen) return one at all?



If this is correct, then "... net-listen returns immediately with a socket number", cannot be correct. At best , it would return with a *potential* socket number, or an intermediate pseudo-socket number, or whatever. So what in reality is it that (net-listen) is returning?

My initial speculation of (net-listen) returrning an intermediate or pseudo-socket number was essentially correct...



The problems lies in using the word "socket" in different contexts. When a server or client is creating a "socket" by specifying an IP address and port number, we could refer to these "sockets" as "local-client-socket" and "local-server-socket".  The "local" socket number is used to bind an IP address and port number pair. Then, the server can LISTEN and the client can try to CONNECT. When the listening server receives a connection request that it understands and is valid, the client and server establish a connection that is mapped onto an IP address and port pair specified by the client *and* another IP address and port pair specified by the server. *This* mapped connection is *also* a socket! So, we could refer to this communications socket as the "com-socket".



Whew! Sockets here, sockets there, SOCKET TO ME BABY!



To summarize, we have three mappings that are all called "sockets". We can get a better grasp on them by using more descriptive names:

local-client socket

local-server-scocket

com-socket.



When the server goes into listen mode, it is blocking. To get around this in newLISP, the docs indicate to use spawn. This hands off the blocked listening process to another process, and the system can continue with other things, such as spawning another listen session to enable mutiple connections.



Note that the local-server-socket number is what is used in *every* spawned listen session.



However, because spawn is not a WIN function, that leaves WIN users stuck with a blocking function. The way out is to access the WIN API and invoke threads, handing off each blocking listen function to a new thread, similar to the use of spawn above.
...it is better to first strive for clarity and correctness and to make programs efficient only if really needed.

\"Getting Started with Erlang\"  version 5.6.2

Lutz

#2
You can do non-blocking socket communications in both Unix and Windows without starting new processes using 'net-select' on the listen-socket in a loop. After establishing a connection you can use 'net-select' again to wait for incoming data on the connection socket without blocking.



There are a few network programming examples here:



http://www.newlisp.org/CodePatterns.html">http://www.newlisp.org/CodePatterns.html



and a general intro into the Berkeley socket API:



http://beej.us/guide/bgnet/">http://beej.us/guide/bgnet/

cormullion

#3
Was that the sound of DrDave volunteering to write an "Introduction to network programming using newLISP"? :)