I don't know how to distinguish data which received in server.
I want to distinguish the data by setting MessageID(example name) when I send data or receive data.
Here's the example.:
server
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host=''
port=int(input(Please Enter the port:))
s.bind((host,port))
s.listen(1)
conn, addr = s.accept()
print('Someone connected.He :%s'%addr)
while True:
data=conn.recv(1024,MessageID) # I want to make this.
print(data)
client
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host=''
port=int(input(Please Enter the port:))
s.connect((host,port))
data='hello world'
data=data.encode('utf-8') # I encoded data because Python 3.3.3's socket module doesn't
work with string(str) when I send data.
s.send(data,MessageID) # This is what I want.I want to set messageID which can distinguish data.
How to make like this?
How other programmers distinguish data in python..?
I really want is : Don't receive if not messageID which server want.
You will need to put the MessageID into the data you're sending. It might be a good idea to use some known protocol for the data, so you know what to expect, but here's a naive example. You will need to implement proper error handling. Note that you will also have to implement a loop to read all of the data, as reading the socket with a single recv will eventually lead to a situation where you're receiving partial messages. I don't really know what your data is so I won't make a guess about it.
The client
....
message_id = 1
data = '{}:hello world!'.format(message_id)
data = data.encode('utf-8')
s.send(data)
The server
while True:
data = conn.recv(1024)
if not data:
# Always handle the case where the client
# connects but sends no data. This means the socket is closed
# by the other end.
break
message_id, message = data.split(":", 1)
print "Got message, id: {}, data: {}".format(message_id, message)
If you'd implement this using pickle or json you could simply use dictionaries:
# Client
data = {'message_id': 1, 'message': 'hello world'}
data = pickle.dumps(data) # Or json.dumps(data)
s.send(data)
# Server
while True:
data = conn.recv(1024)
if not data:
break
data = pickle.loads(data) # Or json.loads(data)
print "Got id: {message_id}, data: {message}".format(**data)
Related
I'm trying to send a command to a remote device: E5071C ENA Vector Network Analyzer
These are my problems:
When I try to send and receive data from the socket, it "hangs".
I am not sure which type of socket I should use.
For the other commands, I used s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM), but I only had to send data in those cases. Here I need to send and receive data. I have tried to use a while Trueloop like this:
while True:
s.settimeout(1)
print(sys.stderr, 'waiting for a connection')
connection, client_address = s.accept()
try:
print(sys.stderr, 'client connected:', client_address)
while True:
data = connection.recv(1024)
print(sys.stderr, 'received "%s"') % data
if data:
connection.sendall(data)
else:
break
finally:
connection.close()
I could not get the result I wanted with the while loop either, so this is what I have so far instead:
## import modules
## for loop iterations
## commands sent to remote device using UDP socket
def is_hanging(host, port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
min_msg = ':CALCulate:SELected:MARKer:FUNCtion:TYPE MINimum'
s.send(min_msg.encode())
s.settimeout(1)
try:
s.recv(1024)
print("Received data!")
return True
except socket.timeout as e:
print(e)
return False
finally:
s.close()
if is_hanging('10.5.33.16',5025) is True:
pass
else:
raise Exception("Could not receive data.")
I am not entirely sure how s.recv works, but I what I am hoping/expecting is that data I send to the remote device generates a response which sent back to me.
Right now it is just hanging.
socket.accept() is only relevant in the context of a stream-based socket that's been configured as a listening socket. It doesn't make sense to use on a datagram socket, especially one that's already associated with a remote host.
(Are you sure SOCK_DGRAM -- i.e. UDP -- is correct here? Most SCPI devices I've worked with use TCP, i.e. SOCK_STREAM.)
If you're sure that you're using the right protocol, remove the call to s.accept(), and call .recv() on the existing socket s.
I'm trying to send a file over a socket in Python 2.7.x . My client and server code is below. It's working, but only after the client connection kills the socket. So I added raw_input('finished') to the end of both for debugging.
So if I start the server, then run the client... It looks like all but the last bit of the file sends, until I forcefully kill the client and then it's all there. So the problem is definitely in the server loop... I just don't know how to fix it. if not data: break isn't being triggered. But, if I do something like if len(data) < 1024: break it won't work for bigger files.
Any help is appreciated!
# client.py
import socket
conn = socket.socket()
conn.connect(('localhost', 1337))
f = open('test.jpg', 'rb')
data = f.read(1024)
while data:
conn.send(data)
data = f.read(1024)
f.close()
raw_input('finished')
# server.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('localhost', 1337))
s.listen(5)
conn, addr = s.accept()
f = open('test.jpg', 'wb')
while True:
data = conn.recv(1024)
if not data:
break
f.write(data)
f.close()
raw_input('finished')
From your posted code:
while data:
conn.send(data)
data = f.read(1024)
From the Python socket documentation:
socket.send(string[, flags])
[...]
Returns the number of bytes sent. Applications are responsible for checking
that all data has been sent; if only some of the data was transmitted, the
application needs to attempt delivery of the remaining data.
That should tell you what the problem is, but just to be explicit about it: send() may or may not accept all of the bytes you asked it to send before returning, and it's up to you to handle it correctly in the case where it only accepts the first (n) bytes rather than the entire buffer. If you don't check send()'s return value, then you will sometimes drop some of the bytes of your file without knowing it. You need to check send()'s return value and if it is less than len(data), call send() again (as many times as necessary) with the remaining bytes. Alternatively you could call conn.sendall() instead of conn.send(), since sendall() will perform that logic for you.
I know that similar questions have been raised but they don't seem to work for me! I have tried serializing the dictionary then converting that to a string then encoding it before I send it over the socket. No success so far!
This is my server code:
#library
import socket
import pickle
#socket initialization
host = "127.0.0.1"
port = 5000
mainAddr = (host, port)
#dict initialization
dataDict = {} #just imagine that dict has content
#create socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #TCP
s.bind((mainAddr))
s.listen(4)
print('program started')
print('listening..')
while True:
try:
conn, addr = s.accept()
print("connection from: "+str(addr))
print("sending message..")
pickle.dumps(dataDict)
print('pickled!')
dataS = str(dataP)
print('stringed!')
dataE = dataS.encode('UTF-8')
print('encoded!')
s.sendto(dataE,addr)
print('data sent!')
except:
pass
s.close()
For the socket initialization, I've tried other types:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #UDP
s = socket.socket()
For the sending part, I've tried these alternatives:
s.send(dataE)
s.send(dataE,addr)
s.sendall(dataE)
s.sendall(dataE,addr)
When I run the program, these get printed out:
program started
listening..
connection from:<insert addr here>
sending message..
pickled!
stringed!
encoded!
Only data sent! is not sent. So I am guessing that it's the sending part that has a problem.
For the client side, here's the code:
#library
import socket
import pickle
#initialization
host = '127.0.0.1'
port = 5000
buffer = 1024
#create socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #TCP
s.connect((host,port))
print('connected!')
#receive dictionary
print('receiving message..')
while True:
data, addr = s.recvfrom(buffer)
print('received!')
dataD = data.decode("UTF-8")
print('decoded!')
dataP = pickle.loads(dataD)
print('unpickled!')
print(str(dataP))
s.close()
In the client terminal, only the following prints:
connected!
receiving message..
On the client side, I've tried changing the order of unpickling and decoding but still, to no avail.
A TCP server socket is not actually used for sending/receiving data; I'm surprised you're not getting an error when calling s.send() or similar on it. Instead, it's a factory for producing individual sockets for each client that connects to the server - conn, in your code. So, conn.sendall() is what you should be using. No address parameter is required, the individual socket already knows who it is talking to. (.send() is unreliable without some extra work on your part; .sendto() is only used with UDP sockets that have not been connected to a particular client.)
I'm trying to develop a chat program in python. I want it to have multiple clients so I'm using threading to handle this. However when I try to send the message to all connected clients, the server only sends it to the client which sent the message. I'm not sure if I'm just missing something obvious but here is the code for the server:
import socket
from thread import *
host = '192.168.0.13'
port = 1024
users = int(input("enter number of users: "))
def clienthandler(conn):
while True:
data = conn.recv(1024)
if not data:
break
print data
conn.sendall(data)
conn.close()
serversock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversock.bind((host, port))
serversock.listen(users)
for i in range(users):
conn, addr= serversock.accept()
print 'Connected by', addr
start_new_thread(clienthandler, (conn,))
And here is the code for the client:
import socket
host = '192.168.0.13'
port = 1024
usrname = raw_input("enter a username: ")
usrname = usrname + ": "
clientsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsock.connect((host, port))
while True:
x = raw_input('You: ')
x = usrname + x
clientsock.sendall(x)
data = clientsock.recv(1024)
print data
The "all" in sendall means that it sends all of the data you asked it to send. It doesn't mean it sends it on more than one connection. Such an interface would be totally impractical. For example, what would happen if another thread was in the middle of sending something else on one of the connections? What would happen if one of the connections had a full queue?
sendall: Send data to the socket. The socket must be connected to a remote socket. The optional flags argument has the same meaning as for recv() above. Unlike send(), this method continues to send data from string until either all data has been sent or an error occurs. None is returned on success. On error, an exception is raised, and there is no way to determine how much data, if any, was successfully sent. -- 17.2. socket
You can try by pulling up the list of users, and iterating through it, and doing an individual send of the same message, though, unless you are the administrator and want to broadcast a warning, this functionality would be pretty mundane.
i am working on some proof of concept study research project and have python udp socket server that listen received data.
Client send data NAME and FAMILY NAME on UDP to server.
I would like to receive that data on UDP socket server side and on receive send this data to mysql database with two fields f_name and l_name.
import socket
UDP_IP = "192.168.1.10"
UDP_PORT = 9000
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))
print "UDP SERVER STARTED!"
while True:
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
print "MSG Received:", data
this example is taken from web and with this server i get data on console.
I would like to have it like below and of course code/concept can be changed. This might be solved with scapy sniffer but that would be dirty.
Conceptually i would like to have ti something like:
1. socekt server received data
2. parse data received and send this data to mysql
I started with this in mind but doesnt work
import socket
import MySQLdb
UDP_IP = "192.168.1.10"
UDP_PORT = 9000
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))
print "UDP SERVER STARTED!"
while True:
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
print "received message:", data
def parse(data):
db = MySQLdb.connect("localhost","db_user","db_pass","directory_db")
cursor = db.cursor()
# Params to insert into DB
f_nameObj = re.search(r'NAME: (.*?) .*', data, re.M|re.I)
if f_name:
f_name = f_nameObj.group(1)
l_nameObj = re.search(r'SURNAME: (.*?) .*', data, re.M|re.I)
if l_name:
l_name = l_nameObj.group(1)
# MySQL EXECUTION
cursor.execute("""
INSERT INTO dictionary (f_name, l_name) VALUES (%s, %s)""",(f_name,l_name))
#
db.commit()
With this kind of udp server i see no messages so seems function that parse data is not working with server.
Any help or guidance would be appreciated
In your server when you receive data you don't call parse function.You just print the content of data. Add the line with the comment and see the result.
while True:
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
print "received message:", data
parse(data) # Call the Function