How can I adapt between non zmq socket and pyzmq? - python

I want to write a bridge adapt between non ZMQ socket and ZMQ socket.
client code:
import socket
if __name__ == '__main__':
HOST = "localhost"
PORT = 8888
BUFFER = 4096
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print sock
ret = sock.connect((HOST, PORT))
print ret
ret = sock.send('hello, tcpServer!')
print ret
recv = sock.recv(BUFFER)
print ('[tcpServer siad]: %s' % recv)
sock.close()
except e:
print e
proxy code, use this proxy to send request to ZMQ_REP server.
import zmq
if __name__ == '__main__':
context = zmq.Context()
socket = context.socket(zmq.STREAM)
socket.bind("tcp://*:8888")
socket_req = context.socket(zmq.REQ)
socket_req.connect("tcp://localhost:5556")
while True:
clientid, message = socket.recv_multipart();
print("id: %r" % clientid)
print("request:",message.decode('utf8'))
socket_req.send(clientid, flags=zmq.SNDMORE, copy=False)
socket_req.send("Hi", copy=False)
clientid, message = socket_req.recv_multipart()
print("id: %r" % clientid)
print("request:",message.decode('utf8'))
ZMQ_REP server code:
import zmq
import time
import sys
if __name__ == '__main__':
port = '5556'
if len(sys.argv) > 1:
port = sys.argv[1]
int(port)
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://*:%s" % port)
while True:
message = socket.recv()
print "Received request: ", message
time.sleep(1)
socket.send("world from %s" % port)
the REQ get error:
Received request: k
Traceback (most recent call last):
File "req_server.py", line 21, in <module>
socket.send("world from %s" % port)
File "zmq/backend/cython/socket.pyx", line 574, in zmq.backend.cython.socket.Socket.send (zmq/backend/cython/socket.c:5434)
File "zmq/backend/cython/socket.pyx", line 621, in zmq.backend.cython.socket.Socket.send (zmq/backend/cython/socket.c:5196)
File "zmq/backend/cython/socket.pyx", line 181, in zmq.backend.cython.socket._send_copy (zmq/backend/cython/socket.c:2035)
File "zmq/backend/cython/checkrc.pxd", line 21, in zmq.backend.cython.checkrc._check_rc (zmq/backend/cython/socket.c:6248)
zmq.error.ZMQError: Operation cannot be accomplished in current state

First point: It's generally not recommended to use REQ/REP in zmq. Use the more general DEALER/ROUTER combination. The only difference:
When the ROUTER recvs, a routing ID is the first part of the message. This is used to route replies back to the sender.
the lock-step req/rep/req/rep sequence is not enforced (this is the error you are seeing).
Here's a version of your proxy using DEALER:
import zmq
if __name__ == '__main__':
context = zmq.Context()
socket = context.socket(zmq.STREAM)
socket.bind("tcp://*:8888")
socket_req = context.socket(zmq.DEALER)
socket_req.connect("tcp://localhost:5556")
while True:
clientid, message = socket.recv_multipart()
print("id: %r" % clientid)
print("request: %s" % message.decode('utf8'))
socket_req.send(message)
reply = socket_req.recv()
print("reply: %s" % reply.decode('utf8'))
socket.send_multipart([clientid, reply])
And your server, using ROUTER:
import zmq
import time
import sys
if __name__ == '__main__':
port = 5556
if len(sys.argv) > 1:
port = int(sys.argv[1])
context = zmq.Context()
socket = context.socket(zmq.ROUTER)
socket.bind("tcp://127.0.0.1:%i" % port)
while True:
message = socket.recv_multipart()
req_id = message[0]
print("Received request: %s" % message[1:])
time.sleep(1)
socket.send_multipart([req_id, "world from %s" % port])

socket_req.send(clientid, flags=zmq.SNDMORE, copy=False)
socket_req.send("Hi", copy=False)
Best guess is that it's not properly registering the SNDMORE flag and attempting to send a whole new request rather than appending to the first one (thus breaking the strict SEND/RECEIVE order for REQ sockets)... thus the "current state" of the socket would not allow it to send the second part of your message. Try using send_multipart(), or validating that your parameters are being passed in correctly.

Related

Monitoring PUB/SUB pattren in ZeroMQ in python

I am using a PUB/SUB patteren.
I need to monitor this.
I got following code for monitor REP/REP patteren, I want something like this for PUB/SUB..
when I am changing PUB/SUB in this but then this code is not working.
Please let me know if how monitoring is possible for PUB/SUB
import time
import zmq
from zmq.devices.basedevice import ProcessDevice
from zmq.devices.monitoredqueuedevice import MonitoredQueue
from zmq.utils.strtypes import asbytes
from multiprocessing import Process
import random
frontend_port = 8888
backend_port = 8882
monitor_port = 5562
number_of_workers = 2
def monitordevice():
in_prefix=asbytes('in')
out_prefix=asbytes('out')
monitoringdevice = MonitoredQueue(zmq.XREP, zmq.XREQ, zmq.PUB, in_prefix, out_prefix)
monitoringdevice.bind_in("tcp://127.0.0.1:%d" % frontend_port)
monitoringdevice.bind_out("tcp://127.0.0.1:%d" % backend_port)
monitoringdevice.bind_mon("tcp://127.0.0.1:%d" % monitor_port)
monitoringdevice.setsockopt_in(zmq.SNDHWM, 1)
monitoringdevice.setsockopt_out(zmq.SNDHWM, 1)
monitoringdevice.start()
print("Program: Monitoring device has started")
def server(backend_port):
print("Program: Server connecting to device")
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("tcp://127.0.0.1:%s" % backend_port)
server_id = random.randrange(1,10005)
while True:
message = socket.recv()
print("Server: Received - %s" % message)
socket.send_string("Response from server #%s" % server_id)
def client(frontend_port, client_id):
print("Program: Worker #%s connecting to device" % client_id)
context = zmq.Context()
socket = context.socket(zmq.REQ)
socket.connect("tcp://127.0.0.1:%s" % frontend_port)
request_num = 1
socket.send_string("Request #%s from client#%s" % (request_num, client_id))
message = socket.recv_multipart()
print("Client: Received - %s" % message)
def monitor():
print("Starting monitoring process")
context = zmq.Context()
socket = context.socket(zmq.SUB)
print("Collecting updates from server...")
socket.connect ("tcp://127.0.0.1:%s" % monitor_port)
socket.setsockopt_string(zmq.SUBSCRIBE, "")
while True:
string = socket.recv_multipart()
print("Monitoring Client: %s" % string)
if __name__ == "__main__":
monitoring_p = Process(target=monitordevice)
monitoring_p.start()
server_p = Process(target=server, args=(backend_port,))
server_p.start()
monitorclient_p = Process(target=monitor)
monitorclient_p.start()
time.sleep(2)
for client_id in range(number_of_workers):
Process(target=client, args=(frontend_port, client_id,)).start()
time.sleep(10)
server_p.terminate()
monitorclient_p.terminate()
monitoring_p.terminate()
when I am changing PUB/SUB in above code then this code is not working.
Please let me know if how monitoring is possible for PUB/SUB

Attempting secure socket communication between client and server and getting An operation was attempted on something that is not a socket error

I am attempting to piece together a secure socket client server communication solution. I do not have experience in doing so, so have cobbled together what I believe are relevant sections. The idea is that the Server waits for connections, the client creates a connection that is secure and then communication can take place.
The code also utilizes secure communication in authorization with client and server keys and certificates.
client code:
class Client:
def __init__(self):
try:
self.host, self.port = "127.0.0.1", 65416
self.client_cert = os.path.join(os.path.dirname(__file__), "client.crt")
self.client_key = os.path.join(os.path.dirname(__file__), "client.key")
self._context = ssl.SSLContext()
self._context.load_cert_chain(self.client_cert, self.client_key)
self._sock = None
self._ssock = None
except Exception as e:
print("Error in Initializing")
def checkvalidclient(self):
# ---- Client Communication Setup ----
HOST = self.host # The server's hostname or IP address
PORT = self.port # The port used by the server
try:
self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._ssock = self._context.wrap_socket(self._sock,)
self._ssock.connect((HOST, PORT))
print ("Socket successfully created")
except socket.error as err:
print ("socket creation failed with error %s" %(err))
print('Waiting for connection')
Response = self._ssock.recv(1024)
while True:
Input = input('Say Something: ')
# s.send(str.encode(Input))
send_msg(self._ssock, str.encode(Input))
# Response = s.recv(1024)
Response = recv_msg(self._ssock)
if Response is not None:
print(Response.decode('utf-8'))
def closesockconnection(self):
self._ssock.close()
# ---- To Avoid Message Boundary Problem on top of TCP protocol ----
def send_msg(sock: socket, msg): # ---- Use this to send
# Prefix each message with a 4-byte length (network byte order)
msg = struct.pack('>I', len(msg)) + msg
sock.sendall(msg)
def recv_msg(sock: socket): # ---- Use this to receive
# Read message length and unpack it into an integer
raw_msglen = recvall(sock, 4)
if not raw_msglen:
return None
msglen = struct.unpack('>I', raw_msglen)[0]
# Read the message data
return recvall(sock, msglen)
def recvall(sock: socket, n: int):
# Helper function to receive n bytes or return None if EOF is hit
data = bytearray()
while len(data) < n:
packet = sock.recv(n - len(data))
if not packet:
return None
data.extend(packet)
return data
client = Client()
client.checkvalidclient()
Server code:
import socket
import os
import ssl
from os import path
from _thread import *
import struct # Here to convert Python data types into byte streams (in string) and back
# ---- To Avoid Message Boundary Problem on top of TCP protocol ----
def send_msg(sock: socket, msg): # ---- Use this to send
# Prefix each message with a 4-byte length (network byte order)
msg = struct.pack('>I', len(msg)) + msg
sock.sendall(msg)
def recv_msg(sock: socket): # ---- Use this to receive
# Read message length and unpack it into an integer
raw_msglen = recvall(sock, 4)
if not raw_msglen:
return None
msglen = struct.unpack('>I', raw_msglen)[0]
# Read the message data
return recvall(sock, msglen)
def recvall(sock: socket, n: int):
# Helper function to receive n bytes or return None if EOF is hit
try:
data = bytearray()
while len(data) < n:
packet = sock.recv(n - len(data))
if not packet:
return None
data.extend(packet)
return data
except Exception as e:
print("Exception in recvall : " + str(e))
# ---- Server Communication Setup
class Server:
def __init__(self):
self.HOST = '127.0.0.1' # Standard loopback interface address (localhost)
self.PORT = 65416 # Port to listen on (non-privileged ports are > 1023)
self.ThreadCount = 0
self.server_cert = path.join(path.dirname(__file__), "server.crt")
self.server_key = path.join(path.dirname(__file__), "server.key")
self.client_cert = path.join(path.dirname(__file__), "client.crt")
self._context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
self._context.verify_mode = ssl.CERT_REQUIRED
self._context.load_cert_chain(self.server_cert, self.server_key)
self._context.load_verify_locations(self.client_cert)
self.sock = None
def connect(self):
try: # create socket
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
print ("Socket successfully created")
except socket.error as err:
print ("socket creation failed with error %s" %(err))
try: # bind socket to an address
self.sock.bind((self.HOST, self.PORT))
except socket.error as e:
print(str(e))
print('Waiting for a Connection..')
self.sock.listen(3)
def threaded_client(self, conn: socket):
conn.send(str.encode('Welcome to the Server'))
while True:
# data = conn.recv(2048) # receive message from client
data = recv_msg(conn)
print(data)
if data is not None:
reply = 'Server Says: ' + data.decode('utf-8')
if not data:
break
# conn.sendall(str.encode(reply))
send_msg(conn, str.encode(reply))
#conn.close()
def waitforconnection(self):
while True:
Client, addr = self.sock.accept()
self._context.wrap_socket(Client, server_side=True)
print('Connected to: ' + addr[0] + ':' + str(addr[1]))
start_new_thread(self.threaded_client, (Client, )) # Calling threaded_client() on a new thread
self.ThreadCount += 1
print('Thread Number: ' + str(self.ThreadCount))
#self.sock.close()
server = Server()
server.connect()
server.waitforconnection()
The lines:
def threaded_client(self, conn: socket):
conn.send(str.encode('Welcome to the Server'))
result in the error:
[WinError 10038] An operation was attempted on something that is not a socket
When I removed the certificate related lines in client:
self.client_cert = os.path.join(os.path.dirname(__file__), "client.crt")
self.client_key = os.path.join(os.path.dirname(__file__), "client.key")
self._context = ssl.SSLContext()
self._context.load_cert_chain(self.client_cert, self.client_key)
and the certificate related lines in the server:
self.server_cert = path.join(path.dirname(__file__), "server.crt")
self.server_key = path.join(path.dirname(__file__), "server.key")
self.client_cert = path.join(path.dirname(__file__), "client.crt")
self._context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
self._context.verify_mode = ssl.CERT_REQUIRED
self._context.load_cert_chain(self.server_cert, self.server_key)
self._context.load_verify_locations(self.client_cert)
self.sock = None
and a couple of small changes to remove the certificate related functionality, everything seemed to work, the client could send messages to the server and the server could respond (and the client displayed the response).
When however I added the context related certificates I start getting the error:
An operation was attempted on something that is not a socket
The server waits at:
Client, addr = self.sock.accept()
and continues to run once the client has called (in the client.py file):
self._ssock.connect((HOST, PORT))
The server then reaches the lines:
def threaded_client(self, conn: socket):
conn.send(str.encode('Welcome to the Server'))
where it fails on this error.
Printing the terminal, a traceback and exception error results in:
Socket successfully created
Waiting for a Connection..
Connected to: 127.0.0.1:57434
Thread Number: 1
Traceback (most recent call last):
File "c:\testcode\Server.py", line 71, in threaded_client
conn.send(str.encode('Welcome to the Server'))
OSError: [WinError 10038] An operation was attempted on something that is not a socket
My knowledge is limited and I cannot find more examples of secure multi threaded two way communication client to server socket code. The idea is to ensure the client is authorized to communicate with the server before transmission happens.
Any ideas on where I am failing?
Thanks
Ok, It seems like I was close, but had a couple of tweaks to do.
The solution of:
SSL/TLS client certificate verification with Python v3.4+ SSLContext
and the commenters here, helped me get over the finish line.
Server code:
import socket
import os
from socket import AF_INET, SOCK_STREAM, SO_REUSEADDR, SOL_SOCKET, SHUT_RDWR
import ssl
from os import path
from _thread import *
import struct # Here to convert Python data types into byte streams (in string) and back
import traceback
# ---- To Avoid Message Boundary Problem on top of TCP protocol ----
def send_msg(sock: socket, msg): # ---- Use this to send
# Prefix each message with a 4-byte length (network byte order)
msg = struct.pack('>I', len(msg)) + msg
sock.sendall(msg)
def recv_msg(sock: socket): # ---- Use this to receive
# Read message length and unpack it into an integer
raw_msglen = recvall(sock, 4)
if not raw_msglen:
return None
msglen = struct.unpack('>I', raw_msglen)[0]
# Read the message data
return recvall(sock, msglen)
def recvall(sock: socket, n: int):
# Helper function to receive n bytes or return None if EOF is hit
try:
data = bytearray()
while len(data) < n:
packet = sock.recv(n - len(data))
if not packet:
return None
data.extend(packet)
return data
except Exception as e:
print("Exception in recvall : " + str(e))
# ---- Server Communication Setup
class Server:
def __init__(self):
self.HOST = '127.0.0.1' # Standard loopback interface address (localhost)
self.PORT = 65416 # Port to listen on (non-privileged ports are > 1023)
self.ThreadCount = 0
self.server_cert = path.join(path.dirname(__file__), "server.crt")
self.server_key = path.join(path.dirname(__file__), "server.key")
self.client_cert = path.join(path.dirname(__file__), "client.crt")
self._context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
self._context.verify_mode = ssl.CERT_REQUIRED
self._context.load_cert_chain(certfile=self.server_cert, keyfile=self.server_key)
self._context.load_verify_locations(cafile=self.client_cert)
self.sock = None
def connect(self):
try: # create socket
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) ###<-- socket.socket() ???
print ("Socket successfully created")
except socket.error as err:
print ("socket creation failed with error %s" %(err))
try: # bind socket to an address
self.sock.bind((self.HOST, self.PORT))
except socket.error as e:
print(str(e))
print('Waiting for a Connection..')
self.sock.listen(3)
def threaded_client(self, conn: socket):
try:
conn.send(str.encode('Welcome to the Server'))
while True:
data = recv_msg(conn)
print("data")
print(data)
if data is not None:
reply = 'Server Says: ' + data.decode('utf-8')
if not data:
break
send_msg(conn, str.encode(reply))
except Exception as e:
print(traceback.format_exc())
print(str(e))
finally:
print("Closing connection")
conn.shutdown(socket.SHUT_RDWR)
conn.close()
#conn.close()
def waitforconnection(self):
while True:
Client, addr = self.sock.accept()
conn = self._context.wrap_socket(Client, server_side=True)
print('Connected to: ' + addr[0] + ':' + str(addr[1]))
print("SSL established. Peer: {}".format(conn.getpeercert()))
start_new_thread(self.threaded_client, (conn, )) # Calling threaded_client() on a new thread
self.ThreadCount += 1
print('Thread Number: ' + str(self.ThreadCount))
#self.sock.close()
server = Server()
server.connect()
server.waitforconnection()
Client code:
import socket
import struct # Here to convert Python data types into byte streams (in string) and back
import sys
import ssl
import socket
import selectors
import types
import io
import os
import time
import requests
from pathlib import Path
import mysql.connector as mysql
from loguru import logger as log
from utils.misc import read_py_config
import json
import rsa
import base64
class Client:
def __init__(self):
self.host, self.port = "127.0.0.1", 65416
self.client_cert = os.path.join(os.path.dirname(__file__), "client.crt")
self.client_key = os.path.join(os.path.dirname(__file__), "client.key")
self.server_crt = os.path.join(os.path.dirname(__file__), "server.crt")
self.sni_hostname = "example.com"
self._context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH, cafile=self.server_crt)
self._context.load_cert_chain(certfile=self.client_cert, keyfile=self.client_key)
self._sock = None
self._ssock = None
def checkvalidclient(self):
# ---- Client Communication Setup ----
HOST = self.host # The server's hostname or IP address
PORT = self.port # The port used by the server
try:
self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._ssock = self._context.wrap_socket(self._sock, server_side=False, server_hostname=self.sni_hostname)
self._ssock.connect((HOST, PORT))
print ("Socket successfully created")
except socket.error as err:
print ("socket creation failed with error %s" %(err))
print('Waiting for connection')
Response = self._ssock.recv(1024)
if Response is not None:
print(Response.decode('utf-8'))
while True:
Input = input('Say Something: ')
send_msg(self._ssock, str.encode(Input))
Response = recv_msg(self._ssock)
if Response is not None:
print(Response.decode('utf-8'))
def closesockconnection(self):
self._ssock.close()
# ---- To Avoid Message Boundary Problem on top of TCP protocol ----
def send_msg(sock: socket, msg): # ---- Use this to send
# Prefix each message with a 4-byte length (network byte order)
msg = struct.pack('>I', len(msg)) + msg
sock.sendall(msg)
def recv_msg(sock: socket): # ---- Use this to receive
# Read message length and unpack it into an integer
raw_msglen = recvall(sock, 4)
if not raw_msglen:
return None
msglen = struct.unpack('>I', raw_msglen)[0]
# Read the message data
return recvall(sock, msglen)
def recvall(sock: socket, n: int):
# Helper function to receive n bytes or return None if EOF is hit
data = bytearray()
while len(data) < n:
packet = sock.recv(n - len(data))
if not packet:
return None
data.extend(packet)
return data
Also ensure (as per the link) that the certificate creation is correct.
There is also another useful link at:
Exploring HTTPS With Python
Which covers HTTPS, specifically the Wireshark section allows you to monitor the traffic from client to server. After completing the above and deploying Wireshark I see that the data is encrypted. Any editing of the certificates (manually) causes the app to fail.
There still needs to be additions of try and except if the communication is halted midway etc. But hoping it will smooth the journey for others.
Thanks to the commenters, helped lead me on the way to solution.

UDP server can't send packet to the client

I have two computer(A and B) in the different VLAN.
the IP of the computer A server is x.x.180.70 and IP of the computer B is x.x.181.52.
the computer A bind 19999 port as the UDP server and B as the client.
A can recv the packet from B, but B can't recv the packet from A.
so i capture the packet with wireshark, the results shown that the server reply packet with another port. In common the server reply packet with the bound port. Why does the server use the different port?
Then I wrote a TCP Server on computer A, it works well.
The udp server works if A and B at the same vlan. Is there any body have idea? thanks!
Code(Python):
#!/usr/bin/python3
#coding=utf-8
import socket
import sys
def server(addr):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(addr)
print("server started, listen on %s" % str(addr))
while True:
print("wait msg....")
data, cconn = sock.recvfrom(1024)
client_addr = "%s:%d" % (cconn[0], cconn[1])
resp = "hello client"
print("recv msg from %s <- %s" % (client_addr, data.decode('utf-8')))
sock.sendto(resp.encode("utf-8"), cconn)
print("send msg to %s -> %s" % (client_addr, resp))
def client(addr):
server_addr = "%s:%d" % (addr[0], addr[1])
print("send msg to %s" % server_addr)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.connect(addr)
sock.sendto("hello server".encode("utf-8"), addr)
data, conn = sock.recvfrom(1024)
resp = data.decode("utf-8")
print("recv msg from %s <- %s" % (server_addr, resp))
def usage():
print("Usage:")
print(" python3 udp.py server [ip:port]")
print(" python3 udp.py client [ip:port]")
if __name__ == "__main__":
if len(sys.argv) < 3:
usage()
exit(0)
role = sys.argv[1]
array = sys.argv[2].split(":")
address = (array[0], int(array[1]))
if role == "server":
server(address)
elif role == "client":
client(address)
else:
usage()

How can I make multiclient server in python using multithreading?

This is the code that I have used.But I don't get actual result that I want.When I execute code ChatServer file works properly,but ChatClient gives only one line(Usage : python telnet.py hostname port).Please Help me.I am new in python.
The server code:
#!/usr/bin/env python
#!/usr/bin/env python
"""
A basic, multiclient 'chat server' using Python's select module
with interrupt handling.
Entering any line of input at the terminal will exit the server.
"""
import select
import socket
import sys
import signal
from communication import send, receive
BUFSIZ = 1024
class ChatServer(object):
""" Simple chat server using select """
def __init__(self, port=3490, backlog=5):
self.clients = 0
# Client map
self.clientmap = {}
# Output socket list
self.outputs = []
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server.bind(('',port))
print 'Listening to port',port,'...'
self.server.listen(backlog)
# Trap keyboard interrupts
signal.signal(signal.SIGINT, self.sighandler)
def sighandler(self, signum, frame):
# Close the server
print 'Shutting down server...'
# Close existing client sockets
for o in self.outputs:
o.close()
self.server.close()
def getname(self, client):
# Return the printable name of the
# client, given its socket...
info = self.clientmap[client]
host, name = info[0][0], info[1]
return '#'.join((name, host))
def serve(self):
inputs = [self.server,sys.stdin]
self.outputs = []
running = 1
while running:
try:
inputready,outputready,exceptready = select.select(inputs, self.outputs, [])
except select.error, e:
break
except socket.error, e:
break
for s in inputready:
if s == self.server:
# handle the server socket
client, address = self.server.accept()
print 'chatserver: got connection %d from %s' % (client.fileno(), address)
# Read the login name
cname = receive(client).split('NAME: ')[1]
# Compute client name and send back
self.clients += 1
send(client, 'CLIENT: ' + str(address[0]))
inputs.append(client)
self.clientmap[client] = (address, cname)
# Send joining information to other clients
msg = '\n(Connected: New client (%d) from %s)' % (self.clients, self.getname(client))
for o in self.outputs:
# o.send(msg)
send(o, msg)
self.outputs.append(client)
elif s == sys.stdin:
# handle standard input
junk = sys.stdin.readline()
running = 0
else:
# handle all other sockets
try:
# data = s.recv(BUFSIZ)
data = receive(s)
if data:
# Send as new client's message...
msg = '\n#[' + self.getname(s) + ']>> ' + data
# Send data to all except ourselves
for o in self.outputs:
if o != s:
# o.send(msg)
send(o, msg)
else:
print 'chatserver: %d hung up' % s.fileno()
self.clients -= 1
s.close()
inputs.remove(s)
self.outputs.remove(s)
# Send client leaving information to others
msg = '\n(Hung up: Client from %s)' % self.getname(s)
for o in self.outputs:
# o.send(msg)
send(o, msg)
except socket.error, e:
# Remove
inputs.remove(s)
self.outputs.remove(s)
self.server.close()
if __name__ == "__main__":
ChatServer().serve()
The chat client:
#! /usr/bin/env python
"""
Simple chat client for the chat server. Defines
a simple protocol to be used with chatserver.
"""
import socket
import sys
import select
from communication import send, receive
BUFSIZ = 1024
class ChatClient(object):
""" A simple command line chat client using select """
def __init__(self, name, host='127.0.0.1', port=3490):
self.name = name
# Quit flag
self.flag = False
self.port = int(port)
self.host = host
# Initial prompt
self.prompt='[' + '#'.join((name, socket.gethostname().split('.')[0])) + ']> '
# Connect to server at port
try:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((host, self.port))
print 'Connected to chat server#%d' % self.port
# Send my name...
send(self.sock,'NAME: ' + self.name)
data = receive(self.sock)
# Contains client address, set it
addr = data.split('CLIENT: ')[1]
self.prompt = '[' + '#'.join((self.name, addr)) + ']> '
except socket.error, e:
print 'Could not connect to chat server #%d' % self.port
sys.exit(1)
def cmdloop(self):
while not self.flag:
try:
sys.stdout.write(self.prompt)
sys.stdout.flush()
# Wait for input from stdin & socket
inputready, outputready,exceptrdy = select.select([0, self.sock], [],[])
for i in inputready:
if i == 0:
data = sys.stdin.readline().strip()
if data: send(self.sock, data)
elif i == self.sock:
data = receive(self.sock)
if not data:
print 'Shutting down.'
self.flag = True
break
else:
sys.stdout.write(data + '\n')
sys.stdout.flush()
except KeyboardInterrupt:
print 'Interrupted.'
self.sock.close()
break
if __name__ == "__main__":
import sys
if len(sys.argv)<3:
sys.exit('Usage: %s chatid host portno' % sys.argv[0])
client = ChatClient(sys.argv[1],sys.argv[2], int(sys.argv[3]))
client.cmdloop()
###############################################################################
# The communication module (communication.py)
###############################################################################
import cPickle
import socket
import struct
marshall = cPickle.dumps
unmarshall = cPickle.loads
def send(channel, *args):
buf = marshall(args)
value = socket.htonl(len(buf))
size = struct.pack("L",value)
channel.send(size)
channel.send(buf)
def receive(channel):
size = struct.calcsize("L")
size = channel.recv(size)
try:
size = socket.ntohl(struct.unpack("L", size)[0])
except struct.error, e:
return ''
buf = ""
while len(buf) < size:
buf = channel.recv(size - len(buf))
return unmarshall(buf)[0]

Python Panda3D - Render using Coordinates

I have encountered an error, i'm trying to render a character using coordinates of the character and then using the code reparentTo(render), however i get the following error: "TypeError: must be string or buffer, not None".
Traceback:
File "C:\On
line.py", line 1857, in <module>
run()
File "C:\Panda3D-1.8.1\direct\showbase\ShowBase.py", line 2921, in run
self.taskMgr.run()
File "C:\Panda3D-1.8.1\direct\task\Task.py", line 502, in run
self.step()
File "C:\Panda3D-1.8.1\direct\task\Task.py", line 460, in step
self.mgr.poll()
File "C:\On
line.py", line 1591, in updaterender
s.send(x)
TypeError: must be string or buffer, not None
Part of the Client code:
import direct.directbase.DirectStart
import pickle
from direct.gui.OnscreenText import OnscreenText
from direct.gui.DirectGui import *
from panda3d.core import *
from pandac.PandaModules import CardMaker
from pandac.PandaModules import NodePath
import socket
import sys
import select
print("Connecting...")
name = "fatie"
print 'Please enter the name you wish to use for your pirate?'
name = raw_input()
host = 'localhost'
port = 8303
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(2)
# connect to remote host
try :
s.connect((host, port))
except :
print 'Unable to connect'
sys.exit()
#When the connection is established the game loads.
#So if the code "Connected" comes up, the connection has been established.
print("Connected")
print("Loading Game")
#Game Loads Info connection to files then half way down the code
def updatecoords(task):
s.send(name)
print 'Name sent...'
def updatepos(task):
y = format(Cat.getPos())
s.send(y)
def updaterender(task):
x = Cat.reparentTo(render)
s.send(x)
return Task.cont
print 'Position sent'
def readServer(task):
try:
data = s.recv(4096)
print data
return Task.cont
except:
print 'no data received'
#Then further down
base.taskMgr.add(handleMovement, 'controlManager')
base.taskMgr.add(updatecoords, 'network coords')
base.taskMgr.add(updaterender, 'network coords')
base.taskMgr.add(updatepos, 'network coords')
base.taskMgr.add(readServer, 'read in')
Server Code:
import socket
import time
import pickle
import select
def broadcast(sock, message):
for socket in CONNECTION:
if socket != server_socket and socket != sock :
try :
socket.send(message)
except :
# broken socket connection may be, chat client pressed ctrl+c for example
socket.close()
CONNECTION.remove(socket)
HOST = ""
PORT = 8303
CONNECTION = []
RECV_BUFFER = 4096
maxclients = 5
print "Online Server started on port " + str(PORT)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('',PORT))
server_socket.listen(maxclients)
CONNECTION.append(server_socket)
while 1:
read_socks,wri_socks,err_socks = select.select(CONNECTION,[],[])
for sock in read_socks:
#New connection
if sock == server_socket:
socknew, addr = server_socket.accept()
CONNECTION.append(socknew)
print "Client (%s, %s) connected" % addr
broadcast(socknew, "[%s:%s] entered game\n" % addr)
else:
try:
data = socknew.recv(RECV_BUFFER)
if data:
print data
# broadcast_data(sock,data)
# print 'data was broadcast to'
# print CONNECTION_LIST.len()
except:
broadcast(sock, "Client (%s, %s) is offline" % addr)
sock.close()
CONNECTION.remove(sock)
continue
server_socket.close()

Categories