So let's say I have a Tk interface with 2 buttons. I want one of them to start a server and one of them to close the server.
The code for the start button:
syslog "Server is Opened"
config
socket -server accept 12345
vwait forever
What do I have to write in the stop button to stop this server? Or should starting and stopping the server happen in the same button, and how?
To shut down a server socket, you need to keep its handle around and close it when you no longer want it.
syslog "Server is Opened"
config
set number_of_connected_clients 0
set server [socket -server accept 12345]
vwait until_time_to_stop
close $server
# You probably want some extra time/code here to let clients disconnect gracefully
while {$number_of_connected_clients > 0} {
vwait number_of_connected_clients
}
exit
Then you can trigger a shutdown by doing this (in a callback):
set ::until_time_to_stop "now, please"
The actual value you set the variable to is pretty arbitrary. The tricky part is that you also usually want to let any connected clients finish their business. To make the code above work, just increment the global number_of_connected_clients when a client connects (in the accept procedure probably) and decrement it again when you close your side of the client connection. There's other ways to achieve the same effect (e.g., by keeping client handles in a global array and vwaiting on that at the end with [array size handles] as the test) but it's just a variation on a theme.
Related
I create epoll and register some non-blocking sockets which try connect to closed ports on localhost. Why epoll tells me, that i can write to this socket (it give event for one of created socket with eventmask contain EPOLLOUT)? But this socket doesn't open and if i try send something to it i get an error Connection refused.
Another question - what does mean even EPOLLHUP? I thought that this is event for refused connection. But how in this case event can have simultaneously EPOLLHUP and EPOLLOUT events?
Sample code on Python:
import socket
import select
poll = select.epoll()
fd_to_sock = {}
for i in range(1, 3):
s = socket.socket()
s.setblocking(0)
s.connect_ex(('localhost', i))
poll.register(s, select.EPOLLOUT)
fd_to_sock[s.fileno()] = s
print(poll.poll(0.1))
# prints '[(4, 28), (5, 28)]'
All that poll guarantees is that your application won't block after calling corresponding function. So you are getting what you've paid for - you can now rest assured writing to this socket won't block - and it didn't block, did it?
Poll never guarantees that corresponding operation will succeed.
poll/select/epoll return when the file descriptor is "ready" but that just means that the operation will not block (not that you will necessarily be able to write to it successfully).
Likewise for EPOLLIN: for example, it will return ready when a socket is closed; in that case, you won't actually be able to read data from it.
EPOLLHUP means that there was a "hang up" on the connection. That would really only occur once you actually had a connection. Also, the documentation (http://linux.die.net/man/2/epoll_ctl) says that you don't need to include it anyway:
EPOLLHUP
Hang up happened on the associated file descriptor. epoll_wait(2) will always wait for this event; it is not necessary to set it in events.
I currently have a server that handles multiple connections from clients, and client that connects to the server using two connections. My client has two processes that handle respectively sending and receiving to and from the server, but not both. The problem I currently have is when I want to close the socket, my reading process is stuck on the gen_tcp:recv/2 block. If I put a timeout, the socket is closed when the timeout has been reached. My question is, is it possible to have gen_tcp:recv/3 call that doesn't closes the socket.
This is how my reading process looks like.
read(Socket, Control) ->
Control ! ok,
receive
read ->
case gen_tcp:recv(Socket, 0) of
{ok, Data} ->
%% handling for messages;
Other ->
io:format(Other)
end,
read(self()), %% this sends "read" to itself with "!"
read(Socket, Control);
{error, Reason} ->
io:format(Reason)
end;
close ->
io:format("Closing Reading Socket.~n"),
gen_tcp:close(Socket)
end.
As you can see here, the process will never be able to receive a close if recv/2 doesn't read anything.
Sure, gen_tcp:recv/3 with timeout set to infinity will not close the socket :) See the official documentation.
Edit:
From the documentation:
This function receives a packet from a socket in passive mode.
Check the documentation for setopts/2 to understand the difference between passive and active modes. In particular:
If the value is false (passive mode), the process must explicitly receive incoming data by calling gen_tcp:recv/2,3.
Your process can only do one thing at a time - either listen for the close message from another process or wait for the TCP packet. You could try to use the gen_tcp:controlling_process/2 but I don't know the details. Another solution would be to handle the recv/3 in a separate (third) linked process and kill the process when the close is received.
The better way would be to use an active socket instead, see the Examples section in the official documentation for some guide how to do that.
The best way in my opinion would be to use the OTP gen_server to handle both, the close message and incoming TCP packets in the same process. There is an excellent tutorial in the Erlang and OTP in Action book on how to implement that and here is the code example on Github.
Is it possible to implement the equivalent of Socket.Poll in async/await paradigm (or BeginXXX/EndXXX async pattern)?
A method which would act like NetworkStream.ReadAsync or Socket.BeginReceive but:
leave the data in the socket buffer
complete after the specified interval of time if no data arrived (leaving the socket in connected state so that the polling operation can be retried)
I need to implement IMAP IDLE so that the client connects to the mail server and then goes into waiting state where it received data from the server. If the server does not send anything within 10 minutes, the code sends ping to the server (without reconnecting, the connection is never closed), and starts waiting for data again.
In my tests, leaving the data in the buffer seems to be possible if I tell Socket.BeginReceive method to read no more than 0 bytes, e.g.:
sock.BeginReceive(b, 0, 0, SocketFlags.None, null, null)
However, not sure if it indeed will work in all cases, maybe I'm missing something. For instance, if the remote server closes the connection, it may send a zero-byte packet and not sure if Socket.BeginReceive will act identically to Socket.Poll in this case or not.
And the main problem is how to stop socket.BeginReceive without closing the socket.
What I want to know is whether a process Pid gets terminated when the socket closes if the controlling process is created using gen_tcp:controlling_process(Socket, Pid), and also under what conditions does the socket send this message {tcp_closed, Socket}? Is there a way to prevent the socket on the server side from closing, or is that always normal? Also is there any specific way to terminate a process knowing the Pid?
gen_tcp:controlling_process(Socket, Pid) is used to give the control of a Socket to the process Pid. It implies nothing about the behavior of this process when the Socket is closed.
There are to cases to consider:
You open the server Socket in the mode {active,false} in this case the server will know that the Socket is closed when it calls the function gen_tcp:recv(Sock, Len) getting the answer {error, closed} instead of the expected {ok, Binary}. I recommend you to use this mode if you intend to use gen_tcp:controlling_process(Socket, Pid) because it allow you to avoid a race condition in your code.
You open the server Socket in the mode {active,true} or {active,once}, in this case, the server will receive a message {tcp_closed, Socket}. In this case, there is a race condition see topic Erlang: Avoiding race condition with gen_tcp:controlling_process
I don't think it is the role of the server to prevent any Socket to close, but rather to always be ready to accept a connection.
Last it is always possible to terminate a process, using your own protocol for a smooth end for example Pid ! {stop,Reason} or a more brutal way using exit(Pid, Reason).
I am writing my first socket program to connect to my host to server running on other PC.
I am referring following link but did not got what is the meaning of this line.
http://www.thegeekstuff.com/2011/12/c-socket-programming/
The call to the function ‘listen()’ with second argument as ’10′
specifies maximum number of client connections that server will queue
for this listening socket.
Means to say that it will listen 10 times to new connection request. what actually happen at listen :?:
We will enter while loop once some client connect onto the socket right And inside while loop does accept blocks if no client is requesting to connect to socket on second loop of while :?:
When we are inside while loop does listen() system call is still working or terminates :?:
Also when we will get out of while loop :?:
Please can someone on forum can help me to understand this.
What the listen call does is tell the system the size of the queue it should use for new connections. This queue is only used for connections you have not accepted yet, so it's not the number of total connections you will have.
Besides setting the size of the incoming-connections queue, it also sets a flag on the socket that says it's a passive listening socket.
The stuff that listen does is set on the socket, so as long as the socket is open the queue and the flag is valid.