I asked how to make TCP server that send data all the time in here: Julia TCP select and it works great. I now I have new problem, so I thought to start new conversation.
I did this kind of connection like on the picture:
So Sender sends sometimes something to server 1 and server 1 reads it and updates what to send to server 2 and Server 2 calculates numbers and communicates with C program.
Here is my server 1 code:
notwaiting = true
message = zeros(10,14)
server = listen(5001)
connection = connect(5003)
while true
if notwaiting
notwaiting = false
# Runs accept async (does not block the main thread)
#async begin
sock = accept(server)
reply= read(sock, Float64, 11)
message[:,convert(Int64,reply[1])] = reply[2:11]
write(connection,reshape(message,140))
global notwaiting = true
end
end
write(connection,reshape(message,140))
if message[1,1] == -1.0
close(connection)
close(server)
break
end
sleep(0.01) # slow down the loop
end
Sender is:
Connection2= connect(5001)
message = [2.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0]
write(Connection2,message)
close(Connection2)
And server 2 is like this:
function Server2_connection()
println("Waiting for connection")
server2 = listen(5003)
conn_2 = accept(server2)
while isopen(conn_2)
try
message_server2 = round(read(conn_2,Float64,140),3)
ins_matrix = reshape(message_server2[1:140],10,14)
catch e
println("caught an error $e")
break
end
end
println("Connection closed")
close(conn)
close(server)
end
The problem is that everything together is really heavy. I mean that I can send 2 messages from sender and everything is running really slow. I can run the whole thing 10-15s and then it freezes. All the connections work, but really slowly. My question is am I missing something or have something that makes the servers really slow? How can I code this better way?
I don't have anymore problem with slowness. I got help from julia-users google forum and on of them(Tanmay K. Mohapatra) wrote better code for same purpose: https://gist.github.com/tanmaykm/c2ab61a52cc5afa0e54fe61905a48ef1 It works
same way.
One problem with both codes is that they don't close connections properly. If server 2 goes down, the server 1 gets writing error and server 1 stays in listen mode.
Other ways it works. Thanks to Tanmay!
Edit: found the slower....the thing what should slow things down, did it. The sleep command did slow things down, but it slowed down more than I expected. If I had sleep variable 0.001 seconds, it will slow down the whole system like 0.014s. So I removed sleep command and it works fine.
Related
I have the following code:
...
namespace ba = boost::asio;
...
ba::ip::tcp::resolver resolver(ioService);
ba::ip::tcp::socket sock(ioService);
ba::ip::tcp::resolver::query query(the_ip, the_port);
ba::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
ba::ip::tcp::resolver::iterator end;
boost::system::error_code error = ba::error::host_not_found;
while (error && (endpoint_iterator != end))
{
sock.close();
sock.connect(*endpoint_iterator++, error);
}
When the server is up, it connects instantly and the rest of the code flows wonderfully, but when the server is offline or unreachable this while takes forever to exit.
Before the while: 09:04:37
When it exits: 09:05:40
Since I give query ONE IP and ONE PORT, shouldn't it exit instantly, given no connection can be established?
Are there any parameters I didn't configure? Something like "try X times" or "try for Y seconds"?
EDIT:
As seen in the comments, the problem seems to be a search on the internet, but the connection is local! (192.168...)
Why does it search the internet for a local IP?
As #MartinJames said on the comments:
"The internet is quite big, and has all sorts of links, some with very high latency.
Determining unreachability therefore takes a long time.
That is what happens when you connect all the computers on a planet together."
I tried disconnecting from the internet and the while exited instantly.
But the IP I'm using is local (192.168...), so this is still strange.
Thanks, man.
I'm new to LUA and I'm writing a tcp messaging library in LUA using Corona SDK. I stuck with a problem that socket reading operation hangs application UI even if it is run in coroutine.
How I start coroutine:
function Messaging:readLoop()
self.readCoroutine = coroutine.create(function() self:blockingLoop() end)
coroutine.resume(self.readCoroutine)
end
Blocking loop:
function Messaging:blockingLoop()
line,err,rest = self.sock:receive(BUFSIZE) -- <= Hangs UI if there is no incoming data
end
Of course I know that coroutines are not equal to threads, but I expected that LUA interpreter switched to another coroutine on blocking operation (like Python threads with GIL).
Is there any possibility to read from socket without blocking UI? For example with real threading or async approach? Thanks.
P.S. Eliminating BUFSIZ is not the option since I don't want to have UI blocked at all, even for 0.2..0.4 seconds (slow mobile network delay)
Corona contains LuaSockets which will let you do asynchronous socket communication, as seen here.
Corona has a network.request API for Asynchronous calls..
If you do not want to use that, take a look at this asynchronous http library.
Based on links posted by Mud and SatheeshJM, I finally made a messaging class which might be helpful for somebody
-- Messaging prototype
Messaging = {sock = nil, sockTimer = nil}
-- Messaging constructor
function Messaging:new (o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
function Messaging:connect()
self.sock = socket.tcp()
print( self.sock:connect(HOST, PORT) )
self.sock:settimeout(0)
self.sockTimer = timer.performWithDelay(50, function() self:checkData() end, 0)
end
function Messaging:close()
timer.cancel(self.sockTimer)
self.sock:close()
end
function Messaging:checkData()
local data, status, rest = self.sock:receive()
local s
if data then
s = data
else
s = rest
end
if s:len() ~= 0 then
print ('received', s)
end
end
Important notes:
self.sock:settimeout(0) required to make socket non-blocking
local data, status, rest = self.sock:receive() <- In most cased data will be in "rest" variable when "timeout" error appeared, that is why we need a check below to learn how exactly the data transfered
I am programming a server application to receive requests and answer using the vb.net socket class. I am using the socket.receive and first time is ok but the second time it always return 0 bytes. I can see, with a sniffer, that there is data in the port. I can see that we past the 3 first steps of the communication good and I can see the data in the port, but my socket.receive instruction always return 0 bytes (Sometimes it works the first time and the second stop but some times since the first time it return 0)
I have followed a lot of recommendation found but nothing works, for example: Use the socket.available before the instruction socket.receive, put the socket.receive in a cycle to wait for the complete message, clear the socket buffer.
This is the portion of my code for the socket.receive instruction:
Try
While True
If vConnectionSocket.Available > 0 Then
vNumOfBytesReceived = vConnectionSocket.Receive(Data, 0, vMessageLength, SocketFlags.None)
Array.Copy(Data, indbuf, vClientMessage, indbuf, vNumOfBytesReceived)
If vStrMsg.IndexOf(ChrW(3)) > -1 Then
Exit While
End If
Array.Clear(Data, 0, Data.Length)
End If
End While
Catch ex As SocketException
If vConnectionSocket.Connected Then vConnectionSocket.Close()
MessageBox.Show("Receiving error >" + ex.ErrorCode.ToString + ":" + ex.Message.ToString)
Exit Sub
End Try
I appreciate any help.
Read the documentation:
If you are using a connection-oriented Socket, the Receive method will read as much data as is available, up to the number of bytes specified by the size parameter. If the remote host shuts down the Socket connection with the Shutdown method, and all available data has been received, the Receive method will complete immediately and return zero bytes.
In other words, when Receive() return 0, the connection was closed by the other party. There is no more data available to read. Close your end of the connection.
I have an intermittent problem with a telnet based server on Unix (the problem crops up on both AIX and Linux).
The server opens two sockets, one to a client telnet session, and one to a program running on the same machine as the server. The idea is that the data is passed through the server to and from this program.
The current setup has a loop using select to wait for a "read" file descriptor to become available, then uses select to wait for a "write" file descriptor to become available.
Then the program reads from the incoming file descriptor, then processes the data before writing to the outgoing descriptor.
The snippet below shows what is going on. The problem is that very occasionally the read fails, with errno being set to ECONNRESET or ETIMEDOUT. Neither of these are codes documented by read, so where are they coming from?
The real question is, how can I either stop this happening, or handle it gracefully?
Could doing two selects in a row be the problem?
The current handling behaviour is to shut down and restart. One point to note is that once this happens it normally happens three or four times, then clears up. The system load doesn't really seem to be that high (it's a big server).
if (select(8, &readset, NULL, NULL, NULL) < 0)
{
break;
}
if (select(8, NULL, &writeset, NULL, NULL) < 0)
{
break;
}
if (FD_ISSET(STDIN_FILENO, &readset)
&& FD_ISSET(fdout, &writeset))
{
if ((nread = read(STDIN_FILENO, buff, BUFFSIZE)) < 0)
{
/* This sometimes fails with errno =
ECONNRESET or ETIMEDOUT */
break;
}
}
Look at the comments in http://lxr.free-electrons.com/source/arch/mips/include/asm/errno.h on lines 85 and 98: these basically say there was a network connection reset or time out. Check and see if there are timeouts you can adjust on the remote network program, or send some periodic filler bytes to ensure that the connection stays awake consistently. You may just be victim of an error in the network transit path between the remote client and your local server (this happens to me when my DSL line hiccups).
EDIT: not sure what the downvote is for. The man page for read explicitly says:
Other errors may occur, depending on the object connected to fd.
The error is probably occuring in the select, not in the read: you're not checking errors after the select, you're just proceeding to the read, which will fail if the select returned an error. I'm betting if you check the errno value after the select call you'll see the errors: you don't need to wait for the read to see the errors.
[Disclaimer: my knowledge of sockets is very rusty, and I'm just getting into R, so if I missed something completely obvious, please point it out!]
If I understand the (sparsely-documented) R functions for creating and managing sockets, namely socketConnection and make.socket, it appears that when creating a server socket (server=TRUE), the moral equivalent of the following is carried out:
s = socket(yada yada);
listen(s, ...);
s2 = accept(s, ...);
close(s, ...);
and now I can work with s2 but can't loop to deal with a backlog of incoming connections to s. Is this more-or-less right? Is there any way to keep listening and continue to deal with additional incoming connections after handling the first?
I'd like to know the answer to this one too! ...but in the meantime I can at least suggest a work-around with some limitations:
If you can know HOW MANY clients will connect, then the following should work.
On the server:
n=2 # Number of clients
port=22131
slist=vector('list',n)
# Connect to all clients
for(i in 1:n) slist[i] <- socketConnection('localhost', port=port, server=TRUE)
# Wait for a client to send data, returns the client index
repeat {
avail <- which( socketSelect(slist) )[[1]]
# ...then read and process data, rinse, repeat...
}
On each client:
port=22131
# Connect to server
s <- socketConnection('localhost', port=port)
# ...then send data...
writeLines(c('foo', 'bar'), s)
No, you can touch the back-log on s1.
Window 1:
$ R
s1 = socketConnection(server=T,port=12345)
s2 = socketConnection(server=T, port=98765)
Window 2:
$ nc localhost 12345
If ever I should leave you, it wouldn't be in springtime
Knowing how in spring I'm bewitched by you so
oh no not in springtime, summer, winter, or fall
no never could I leave you at all
Window 3:
$ nc localhost 98765
for Hitler and Germany
Deutschland is happy and gay
we're marching to a faster pace
look out, here comes the Master Race!
Window 1:
readLines(s1,1)
# "if ever I should leave you, it wouldn't be in springtime"
readLines(s2,1)
# "for Hitler and Germany"
readLines(s1,1)
# "knowing how in spring I'm bewitched by you so"