I am new to programming and Python.
I have a very basic python script that connects to server and send a text message:
#!/usr/bin/python
import socket
s = socket.socket()
host = '127.0.0.1'
port = 4106
s.connect((host, port))
message = 'test1'
s.send(message)
print s.recv(1024)
s.close
Everything is fine, except that this message is an HL7 message and needs to wrapped in MLLP
I found this API that I think can do this for me (http://python-hl7.readthedocs.org/en/latest/api.html#mllp-network-client)
So I modified my program to the following, but I keep getting the error message: NameError: name 'MLLPClient' is not defined
#!/usr/bin/python
import socket
import hl7
host = '127.0.0.1'
port = 4106
with MLLPClient(host, port) as client:
client.send_message('test1')
print s.recv(1024)
s.close
You can do this in different ways;
If you import the top-level package
import hl7
You should create the object with its complete name:
with hl7.client.MLLPClient(host, port) as client:
client.send_message('test1')
or you can import only the specific class:
from hl7.client import MLLPClient
and use it like you did in your example.
See the modules documentation for more information.
maybe from hl7 import MLLPClient ?
or maybe do
with hl7.MLLPClient(...) as ...
Related
I am trying to create a simple HTTP Client and I'm having trouble creating a simple socket. I use PyCharm and it highlights the AF_INET attribute of socket.py as non-existent and my script also crashes at runtime when it tries to get the AF_INET property. I checked my imports and I'm sure I have them right. Thanks!
import re
import socket
def getAddress():
address = input('Please enter a http address and a port (example: http://httpbin.org):\n')
parseAddress(address)
def parseAddress(address):
urlMatch = re.compile(r'^(.*:)//([A-Za-z0-9\-\.]+)(:[0-9]+)?(.*)$')
searchResult = urlMatch.match(address)
host = searchResult.group(2)
port = '80'
portTest = searchResult.group(3)
if portTest is not None:
port = portTest.replace(':', '')
connectToServer(host, port)
def connectToServer(host, port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#s.bind((host, port))
#s.send('HTTP REQUEST')
#response = s.recv()
#print(response)
I also checked for any files named socket.py and there aren't any in my project structure. Also when I ctrl+click the socket import it points me to the right file in the Python install folder :(
This is the code I am trying to run. But the program produces a socket.error. I have a network proxy with port 8080 which connects me to the Internet, what more details do I have to add here to create this socket connection?
import socket
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(('www.pythonlearn.com', 80))
mysock.send('GET http://www.pythonlearn.com/code/intro-short.txt HTTP/1.0\n\n')
while True:
data = mysock.recv(512)
if ( len(data) < 1 ) :
break
print data;
mysock.close()
If I run your code I get the error TypeError: a bytes-like object is required, not 'str' from line 5.
Try using: mysock.send(b'GET http://www.pythonlearn.com/code/intro-short.txt HTTP/1.0\n\n') with the b before your string indicating a bytestring.
I too got a type error upon running your code, and did not have an error connecting the socket. When using the socket library, make use of the makefile method so you won't have to deal with annoying details.
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
my_sock_input = mysock.makefile('r')
my_sock_output = mysock.makefile('w')
Now my_sock_input can use methods like readline(), without any details on bytes to reserve or wotnot. Same convenience stuff for output, but with write. Remember to close all of them!
As to your problem, I tried writing similar things using my makefile variables and I wasn't recieving any message back. So there is some other issue there.
Now, the solution. A simpler way to download a url and read its contents is using the urllib.request library. If you are on Python 2.7, just import urrlib.
import urllib.request
data = urllib.request.urlopen('http://www.pythonlearn.com/code/intro-short.txt')
readable = data.read()
print(readable)
I want to create a simple communication between a server and a client using sockets. The cliend is supposed to send a message and then the server sends a message to the client.
This is my Client code :
import socket
s = socket.socket()
HOST = '127.0.0.1'
s.connect((HOST, 1234))
s.send('Hi')
print ('Client send')
print s.recv(1024)
s.close
This is my Server's code :
import socket
s = socket.socket()
HOST = '127.0.0.1'
s.bind((HOST, 1234))
s.listen(5)
while True:
c, addr = s.accept()
c.send('Hi client')
c.close()
But it only prints "Client send " .
In your server, after having sent 'Hi client' you must wait for the client to have read the message.
You could do either of two things:
Use shutdown() on the socket in the server, see https://docs.python.org/2/library/socket.html#socket.socket.shutdown
Do a .recv(..) in the server, which will terminate after the client has close'ed
the socket after reading the reply the server sent.
Update: tried it on my system (MacOSX). Started two python interpreters. Pasted the server code verbatim in one; server is now up and running and accepting connections.
In the other python interpreter, the client shell, I did the following
>>> import socket
>>> HOST = '127.0.0.1'
>>> def test():
... s = socket.socket()
... s.connect((HOST, 1234))
... s.send('Hi')
... print s.recv(1024)
... s.close() # <== Note function call here!
...
>>> test()
Hi client
>>> test()
Hi client
>>> test()
Hi client
>>> test()
Hi client
This demonstrates that - at least on my system - the code works as anticipated.
I can't reprocude your problem and therefore vote to close your question.
Here's the code I used:
import socket
import threading
HOST = '127.0.0.1'
PORT = 12345
def client():
s = socket.socket()
s.connect((HOST, PORT))
s.send('Hi')
print ('Client send')
print s.recv(1024)
s.close()
def server():
s = socket.socket()
s.bind((HOST, PORT))
s.listen(5)
c, addr = s.accept()
c.send('Hi client')
c.close()
if __name__ == "__main__":
server = threading.Thread(target=server)
server.start()
client()
server.join()
Here's the output I got:
$ python test.py
Client send
Hi client
If the problem persists, please add additional details to your question about why and how your setup still not works. Maybe the problem is just about how you run the programs. Please add details about this as well.
The underlying problem is that you treat sockets as if they were message-busses (one message at a time, always received fully), where in fact they are streams of bytes.
Nobody guarantees you that sending X bytes of data will reach the opposite side as that. It could be X1, X2, X3, Y1 where X1+X2+X3=X, and Y1 being the beginning of the next message Y. And all other kinds of combinations and errors.
To remedy this, real-world client-server apps use protocols. Take HTPP for example: a request starts always with HTTP, and it ends with two newlines. Within this block, there is the Content-Length header telling the client how many bytes to read then - regardless of chunk sizes.
So to really solve your problem, you either have to write a full fledged protocol, or built upon libraries that do that for you - e.g. Twisted, Nanomsg or ZeroMQ
I was trying to create a python socket server that could send and receive data, so I created a socket on the server using the code here:
import socket
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind(('', 1208))
serversocket.listen(5)
(client,(ip,port)) = serversocket.accept()
Then I tried to create a sample connection from my machine by going to command prompt and typing
telnet www.filesendr.com 1208
However, the console simply replies with "Could not open connection to the host, on port 1208...Connection failed." I went back over my code but couldn't identify the problem. Any help would be greatly appreciated.
I think part of the problem is that after you accept the connection you don't do anything else. Once the accept happens, you get to the end of the script, python exits and closes all open file handles (including the socket you just opened). If you want to be able to talk to yourself through telnet, try something like this:
import socket
import select
import sys
port = 1208
listener = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
listener.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
listener.bind(('',port))
listener.listen(128)
newSock, addr = listener.accept()
while True:
r,w,e = select.select([newSock,sys.stdin],[],[])
if newSock in r:
data = newSock.recv(4096)
sys.stdout.write(data)
if sys.stdin in r:
newSock.send(sys.stdin.readline())
I am kind of new to python. I am currently trying to make and use a list/array of sockets in a program. So I have declared an array as follows:
myCSocks = ['CSock1', 'CSock2', 'CSock3', 'CSock4', 'CSock5']
And I am trying to use my array elements as follows:
myCSocks[i], addr = serverSocket.accept()
message = myCSocks[i].recv(1024)
I am getting the following error:
Traceback (most recent call last):
File "./htmlserv_multi.py", line 22, in <module>
message = myCSocks[i].recv(1024)
AttributeError: 'str' object has no attribute 'recv'
This kind of makes sense to me, it is saying that my array elements are of type String and are not sockets. So I understand what my problem is but I do not know how to remedy it. I have googled "list of sockets python" but did not find anything. Any help will be greatly appreciated. Thank you.
PS: My final objective is to create a very simple multithreaded TCP web server (using python)
CODE:
#! /usr/bin/env python
from socket import *
#does this work?
myCSocks = []
serverSocket = socket(AF_INET, SOCK_STREAM)
serverSocket.bind(('192.168.1.4',12000))
serverSocket.listen(5)
while True:
for i in range(0, len(myCSocks)+1):
myCSocks[i], addr = serverSocket.accept()
try:
for i in range(0, len(myCSocks)):
message = myCSocks[i].recv(1024)
filename = message.split()[1]
f = open(filename[1:])
outputdata = f.read()
myCSocks[i].send('HTTP/1.1 200 OK\r\n\r\n')
for p in range(0, len(outputdata)):
myCSocks[i].send(outputdata[p])
myCSocks[i].close()
except IOError:
connectionSocket.send('HTTP/1.1 404 Bad Request\r\n\r\n')
connectionSocket.send('<HTML><p>ERROR 404: BAD REQUEST!</p></HTML>')
serverSocket.close()
exit()
Have a look at the built-in socket module here (http://docs.python.org/2/library/socket.html). This allows you to create sockets, and send and receive data, and there are simple examples in the online documentation. Your code will probably work if you replace the strings with actual sockets. If you want to store several sockets by name, you could use a dictionary:
theDict = {}
theDict['socket1'] = socket.socket()
etc.
If CSock1 is a class already defined you can just refer to the class objects. However, if you are trying to do a multi-threaded, there's better ways to do that: Multithreaded web server in python. If you are just trying to use sockets, I'd look at Multi Threaded TCP server in Python (the second answer is best).
A very simple echo TCP (SOCK_STREAM) server demonstrating how to implement a multiprocessing server. Makes use of threadPoolExecutor to
accept connections asynchronously.
Server:
import socket
import concurrent.futures
def server_instance(addr):
HOST = addr[0]
PORT = addr[1]
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
print(f"Linked with: {addr}")
while True:
data = conn.recv(1024)
if not data:
break
conn.sendall(data)
return f'DONE'
addresses = [
('127.0.0.1', 65432),
('127.0.0.1', 65431),
('127.0.0.1', 65433),
('127.0.0.1', 65435),
('127.0.0.1', 65434),
]
with concurrent.futures.ThreadPoolExecutor() as executor:
for address, status in zip(addresses, executor.map(server_instance, addresses)):
print(f"{address}: {status}")
A client to send data to server.
Client:
import socket
import sys
HOST = '127.0.0.1'
if len(sys.argv) != 3:
print(f"[*] Usage: python {sys.argv[0]} <PORT> <MESSAGE>")
sys.exit()
PORT = int(sys.argv[1])
print(f"PORT SET TO: {PORT}")
MSG = bytes(sys.argv[2], encoding='utf8')
print(f"MESSAGE SET TO: {MSG}")
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.sendall(MSG)
data = s.recv(1024)
print(f'[r] {repr(data)}')
f-strings require python3.6 and up
concurrent futures require python 3.2 and up