I have a socket server defined below and created a client as well. They are able to communicate each other without issues.
Now, multiple applications needs to connect to this socket server and will push the data. Different clients subscribed to this server will read the data from the server.
How can I have my applications connect to this server and start writing the data even without the client connecting to it.
import socket
import sys
import time
def socket_connection_1():
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind the socket to the port
server_address = ('localhost', 9999)
print >>sys.stderr, 'starting up on %s port %s' % server_address
sock.bind(server_address)
# Listen for incoming connections
sock.listen(1)
while True:
# Wait for a connection
print >>sys.stderr, 'waiting for a connection \n'
connection, client_address = sock.accept()
try:
print >>sys.stderr, 'connection from', client_address
# Receive the data in small chunks and retransmit it
while True:
print 'its true'
# data = connection.recv(16)
data = "This is a test message from python socket \n"
# print >>sys.stderr, 'received "%s"' % data
if data:
print 'data being sent'
print >>sys.stderr, 'sending data back to the client'
connection.sendall(data)
else:
print >>sys.stderr, 'no more data from', client_address
break
time.sleep(60)
finally:
# Clean up the connection
connection.close()
socket_connection_1()
Is this what you are asking?
You have a server application
The server application produces data
You have a client application
The client application can connect to the server application and retrieve the data
You want the server application to produce the data only once, even if multiple clients connect to the server and retrieve the same data
You want the server to be able to produce the data at a time that is independent of when any clients connect to the server
If yes, this is what you are asking, then you have to buffer the data that the server produces somewhere. That "somewhere" can be in a file or in memory.
As an optimization, you can produce and buffer the data only when the first client connects, to avoid wasting resources on producing the data when no client connects.
You will need some logic to decide when to delete ("purge") the buffered data, to free the storage capacity when no more clients will connect.
If your application can produce multiple types of data and your storage capacity is limited, you will need some logic to decide which data to purge to make room for new data that you want to produce.
Now we are getting close to the concept of a "cache".
Related
So I'm trying to get an erlang server started, which will echo back from my python client. I can see the connection is made, however the echo doesn't actually happen. Can anybody point me to the right solution?
I'm using python3 as my client driver.
Here is my erlang server: I start it with echo:accept(6000).
-module(echo).
-export([accept/1]).
%% Starts an echo server listening for incoming connections on
%% the given Port.
accept(Port) ->
{ok, Socket} = gen_tcp:listen(Port, [binary, {active, true}, {packet, line}, {reuseaddr, true}]),
io:format("Echo server listening on port ~p~n", [Port]),
server_loop(Socket).
%% Accepts incoming socket connections and passes then off to a separate Handler process
server_loop(Socket) ->
{ok, Connection} = gen_tcp:accept(Socket),
Handler = spawn(fun () -> echo_loop(Connection) end),
gen_tcp:controlling_process(Connection, Handler),
io:format("New connection ~p~n", [Connection]),
server_loop(Socket).
%% Echoes the incoming lines from the given connected client socket
echo_loop(Connection) ->
receive
{tcp, Connection, Data} ->
gen_tcp:send(Connection, Data),
echo_loop(Connection);
{tcp_closed, Connection} ->
io:format("Connection closed ~p~n", [Connection])
end.
here is my python client:
import socket
import sys
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect the socket to the port where the server is listening
server_address = ('localhost', 6000)
print(sys.stderr, 'connecting to %s port %s' % server_address)
sock.connect(server_address)
try:
# Send data
message = 'This is the message. It will be repeated.'
convertedString = message.encode('utf-8')
print(sys.stderr, 'sending "%s"' % message)
sock.sendall(convertedString)
# Look for the response
amount_received = 0
amount_expected = len(message)
while amount_received < amount_expected:
data = sock.recv(16).decode('utf-8')
amount_received += len(data)
print(sys.stderr, 'received "%s"' % data)
finally:
print(sys.stderr, 'closing socket')
sock.close()
I think the problem is it just hangs after sending, and now it's waiting for a response, I think I might not be receiving the string in the right way.
One issue is that you have {packet, line} and the message does not include a new line, so the echo server keeps waiting for the message to be completed before sending it to the handler.
Also, you should be careful with the active option, as any data that is received during the controlling_process/2 call will remain in the previous handler. You should start the accepted socket with {active, false} and then set it to true | pos_integer() when the socket is managed by the handler.
I am trying to control some test equipment with a TCP connection. The equipment comes with software that you are able to control over TCP. Basically, you can input the IP address and port of the client computer and there is also an indicator light that shows when there is an open listening session on that port (this is all on the equipment software interface)
I have tested this using SocketTest3 (free software) and am able to start a listening session as well as send commands from another computer. Now, I want to control the equipment with Python. I am running the code for the server and client on the same machine as the test equipment (using local IP address). When I simply run the code (with the equipment software closed) I am able to send, receive, and print the messages I send. When I have the equipment software open (necessary for control) I am able to start a listening session (indicator light shows up on equipment software), but nothing happens (no errors and nothing received) when I send commands. The messages are also not sent back to the client to print.
Any ideas? It's probably something very simple that I'm missing.
Server code:
import sys
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
TCP_IP = '127.0.0.1'
TCP_PORT = 8001
s.bind((TCP_IP, TCP_PORT))
s.listen(5)
connection, client_address = s.accept()
BUFFER_SIZE = 20
print 'Address: ', client_address
while 1:
print "receiving..."
data = connection.recv(BUFFER_SIZE)
print data
if not data: break
print "received data:", data
connection.send(data) # echo
connection.close()
Client code:
import socket
TCP_IP = '127.0.0.1'
TCP_PORT = 8001
BUFFER_SIZE = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
print "sending message..."
s.sendall('ST<CR>') # Send command
print "receiving message..."
data = s.recv(BUFFER_SIZE)
s.close()
print "received data:", data
For those wondering what is missing from camerausb's code, I think he was not seeing anything from the client's print statement because he did not use repr() to format the data. I had a similar problem, but this worked for me:
print 'Received', repr(data)
I have an idea like how basic communication between client and server is established. So serialize data streams can be passed between client and server. But I want to know, how socket objects can be passed between two clients: I want to know is it possible to pass socket objects between two clients and both share the same socket instance. Please suggest.
Client class:
import socket
import sys
# create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#connect the socket to the port where server is listening
server_address = ('localhost',2000)
print >>sys.stderr, 'connecting to %s port %s' % server_address
sock.connect(server_address)
#after connection is established, data can be through socket with sendall() and recv()
try:
#send data
message = 'This is Message. It will be repeated'
print >>sys.stderr, 'sending "%s"' % message
sock.sendall(message)
#llok for the response
amount_received = 0
amount_expected = len(message)
while amount_received < amount_expected:
data = sock.recv(16)
amount_received += len(data)
print amount_received
print >>sys.stderr, 'received "%s"' % data
finally:
print >>sys.stderr, 'closing socket'
sock.close()
Server class created to receive message from the client and revert with some message.
Server class:
import socket
import sys
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ("localhost",2000)
print >>sys.stderr, 'starting up on %s port %s' %server_address
sock.bind(server_address)
sock.listen(1)
while True:
print >>sys.stderr, 'waiting for connection'
connection, client_address = sock.accept()
try:
print >>sys.stderr, 'connection from', cleint_address
while True:
data = connection.recv(16)
print >>sys.stderr, 'received "%s"' % data
if data:
print >>sys.stderr, 'sending data back to the client'
connection.sendall(data)
else:
print >>sys.stderr, 'no more data from', client_address
break
finally:
connection.close()
After server started the client connects with server and displays suitable messages. Now instead of sending messages between client and server, I want to send socket object to another client which can be achieved using either TCP or UDP. In TCP, serialization of data is required. I want to know is there any way to wrap socket object and pass it over.
Socket objects can not be transported (or you know, teleported :D ) to another language or anything. At most, you can create a protocol by which an instance of the socket can be transferred to another language. But again, I don't see how it may help you.
You have a server socket listening on 2000 port. And another Java socket may connect to it using a client socket. So, what's the point of sending one of the socket to the another? the communication link is somehow twirled. Like, we can just eat ourself to regenerate us. But that would be impossible
Similarly, at most, you can send an instance of the server socket to the java socket. But on the same computer, the Java won't be able to recreate it, because the port is already being listened by another program.
Next, if two programs could listen on the same port, that would make stealing of data and forging quite easy. So, it is not possible for two programs to listen on the same port.
I think what you are looking for is that, two programs combinedly handle the I/O of the same socket. That is rational, at least.
For that, you should create some sort of bidirectional communication link between these two processes. Like another socket on a different port.
Like S is the Server (the sole owner of the socket S1) meanwhile A and B are the handlers.
S should be listening on two different ports. where only A and B are connected. Then any data that comes to S, at S' discretion would be A or B appropriate, then, A or B will reply to that request. And then S will respond appropriate.
Another approach would be S is the main server socket. and A and B are servers listening on different ports. Whenever data comes to S, S sends it to A or B depending on content.
Thirdly, and the most messy solution would be that, A is the server and it offloads some tasks to B via some sort of communication (server-client or threads or a subprocess) and they handle data appropriately.
The reason of calling it messy is that one has to handle two tasks and its harder to maintain its functionality.
But still, sharing a socket is like using the same page of a copy for two different tasks. Hope it helped
There are some other posts about this issue but none did help me with mine.
I'm trying to build a total simple server - client relationship in python
server.py
#!/usr/bin/python
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("127.0.0.1",8889))
s.listen(1)
try:
while True:
client, add = s.accept()
data = client.recv(1024)
if not data:
print 'No data'
print data
finally:
s.close()
client.py
#!/usr/bin/python
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("127.0.0.1",8889))
try:
while True:
message = 'Foo'
s.send(message)
ans = s.recv(1024)
print ans
finally:
s.close()
I start by running the server first, but when I try to run the client I'm getting this Errno 10054 --> An existing connection was forcibly closed by the remote host
While request the browser with the ip and the related port, I receive some data.
I'm quiet new to networking, so please explain what might be obvious wrong in my code.
EDIT* Main issue is, that the client is somehow wrong, because it returns also an empty string on recv
Thank you in advance
Main issue is, that the client is somehow wrong, because it returns also an empty string on recv
The client isn't receiving anything from the server because the server is not sending anything.
On the server side, after print data, adding client.send(data) will send the string back to the client.
I am guessing:
The server accepts one socket and then does
client, add = s.accept()
data = client.recv(1024)
...
client, add = s.accept()
The client does this in the mean time:
s.send(message)
ans = s.recv(1024) # blocks until timeout
If now an other client connects to the server then client is replaced, the socket garbage collected and closed. s.recv(1024) will then tell that the connection is reset.
Have a look at import select or twisted (google around) to handle multiple connections at once.
I have a Blender code which takes sets of data from a csv file and uses them to rotate a robot arm and a human model in the Game Engine. This code works fine, but now I want to send data across a wireless connection to Blender.
I have a server code set up in Blender (which runs on Python 3)
# Server Program
# Make sure the client is being run on the data generation computer
SERVER_LOOP = True
import socket
import sys
import json
import bge
cont = bge.logic.getCurrentController()
owner = cont.owner
print ('INFO: Starting up')
# Create a TCP/IP socket to listen on
print ('INFO: Creating TCP/IP Socket')
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Prevent from 'ADDRESS ALREADY IN USE' upon restart
print ('INFO: Housekeeping...')
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Bind the socket to port 8081 on all interfaces
server_address = ('localhost', 8081)
print ('INFO: Binding and starting up on %s port %s' % server_address)
server.bind(server_address)
print ('INFO: Server bound')
def send_welcome(cont):
cont.send('SERVER: Welcome'.encode('utf8'))
# Listen for connectons for 5 seconds
server.listen(5)
# Connection is the SOCKET OBJECT for the connection
# Client_address is the connected peer(the client)
connection, client_address = server.accept()
print ('INFO: Connection from', connection.getpeername())
print ('INFO: Sending welcome msg')
send_welcome(connection)
print ()
while SERVER_LOOP:
# Receive data
try:
data = connection.recv(10000)
# Unless there's an error
except OSError:
print (connection)
# Decode the data into usable lists
if type(data) != type(''):
data = data.decode()
# If we want to end the client stream but keep the server running
if data=='end' or data=='End' or data=='END':
print ('INFO: Closing connection with ',connection.getpeername())
connection.shutdown(socket.SHUT_RD | socket.SHUT_WR)
print ()
connection.close()
connection, client_address = server.accept()
print ('INFO: Connection from', connection.getpeername())
print ('INFO: Sending welcome msg')
send_welcome(connection)
print ()
# If we want to stop running the server
elif data=='end server' or data=='End server' or data=='End Server':
print ()
print ('SERVER SHUT DOWN')
SERVER_LOOP = False
# Display when data is loaded back on the client side
else:
# gives feedback in server command line
data = json.loads(data)
owner['test'] = data
print ('CLIENT: %s' % data)
message = 'ping'
connection.send(('SERVER: %s' % message).encode('utf-8'))
print ('SERVER: %s' % message)
And the client code to run with it (this one runs on Python 2.7)
# Client Program
# Make sure the server is being run in Blender
import socket
import time
import json
print 'INFO: Creating Socket'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ip_addr = raw_input('IP: ')
port_addr = raw_input('PORT: ')
# Type 'localhost' in the IP field
# Type '8081' in the PORT field
print 'INFO: Connecting to server'
s.settimeout(5) # Times out if 5 seconds without connecting to client
s.connect((ip_addr, int(port_addr)))
# Listen for welcome
data = s.recv(10000)
print data
print ''
while 1:
message = raw_input('CLIENT: ')
if message=='end' or message=='End' or message=='END':
print ''
print 'SHUTTING DOWN CLIENT, SERVER STILL RUNNING'
s.send(message)
break
elif message=='end server' or message=='End server' or message=='End Server':
print ''
print 'SHUTTING DOWN SERVER'
s.send(message)
break
else:
s.send(message)
data = s.recv(10000)
print data
print 'INFO: Closing socket'
s.close()
print 'INFO: Quitting'
Now, obviously this doesn't do the rotations; it's just a test script to make sure that the data transfer between the two works. And it does - in Blender's system console, the data is displayed just as I want it. However, I have a string debug property in Blender titled "test", which is supposed to display the current number just typed in the client, and it's not until I close the whole program down.
For example:
I run the server script in Blender
I run the client script in IDLE
I type in numbers on the client side
They appear in the system console on the server side, but they do NOT appear in the Game Engine
I close the server from the client side
Now, the last number I typed finally appears on the server side
So the problem is that Blender runs my script and then the Game Engine after it's done, but I want them to run concurrently.
Let me know if my explanation doesn't make sense; I can provide downloads to my stuff if need be.
I don't know if this is still a problem - you posted in February and it's now August, but I was just searching for the answer of a similar problem. Your problem is that Blender doesn't update its frames until a script has finished running. Your game is literally stuck on the first frame it plays because it starts a script as soon as that frame hits, and because of the nature of your script, never ends.
Currently, you use server.listen(5) to mean that it listens to five seconds, but the number 5 in that function refers to the backlog instead of the length of time [source]. socket.listen() will stall your game indefinitely (as far as I understand) just like an infinite loop would.
This may not be the answer you were looking for, but it's definitely an answer.