I am new to socket coding in Python, and I wrote this simple function to connect to a server. It runs in a tkinter window. I have an Entry widget, and it is where you input the IP address of the server to connect to. However, when you click the button to connect, the application hangs and freezes. Here is the code below.
def Test(self):
socket.setdefaulttimeout(5)
lengthInfo = self.lengthEntry.get()
if self.portEntry.get() != '':
portInfo = int(self.portEntry.get())
serverInfo = self.serverEntry.get()
conn = socket.socket()
if not self.portEntry.get():
portInfo = 80
try:
conn = socket.socket()
name = socket.gethostbyname(serverInfo)
conn.connect((name,portInfo))
ans = conn.recv(2048)
self.outputWindow.insert(END, "Connection successful: \n \
port:{}, server:{} ('{}'), '{}' \n".format(portInfo, name, serverInfo, \
ans))
return
except Exception as e:
self.outputWindow.insert(END, str(e) + "\n")
I originally thought it was because there was now timeout, but as you can see, I added a 5 second timeout in the very first line of the code. I assumed it was because the application was having some sort of trouble connecting, but I checked Windows task manager, and under the network section there was no activity. I also ran the program in Ubuntu 14.04 but got the same results.
Any solutions?
The socket waits for 2,048 bytes from the server (conn.recv(2048)) and I guess they never arrive.
Related
I'm using pyst2 to connect to the AMI (Asterisk manager interface). I have a event for shutdown, so it can close it and try to reconnect every minute.
My shutdown event:
def handle_shutdown(event, manager, hass, entry):
_LOGGER.error("Asterisk shutting down.")
manager.close()
host = entry.data[CONF_HOST]
port = entry.data[CONF_PORT]
username = entry.data[CONF_USERNAME]
password = entry.data[CONF_PASSWORD]
while True:
sleep(30)
try:
manager.connect(host, port)
manager.login(username, password)
_LOGGER.info("Succesfully reconnected.")
break
except asterisk.manager.ManagerException as exception:
_LOGGER.error("Error reconnecting to Asterisk: %s", exception.args[1])
It works fine, until Asterisk started up again and it can connect. Instead of connecting I get this error: RuntimeError: threads can only be started once.
Does anybody knows how to do this correctly?
Here is my entire code.
Thanks!
I am trying to learn Django through the course offered by MichiganX on edX. My problem is that the lesson skipped some details, and without them I cannot get the code to work.
Code looks like this:
from socket import *
def createServer():
serversocket = socket(AF_INET, SOCK_STREAM)
try:
serversocket.bind(('localhost', 9000))
serversocket.listen(5)
while 1:
(clientsocket, address) = serversocket.accept()
rd = clientsocket.recv(5000).decode()
pieces = rd.split('\n')
if len(pieces) > 0:
print(pieces[0])
data = "HTTP/1.1 200 OK\r\n"
data += "Content-Type: text/html; charset=UTF-8\r\n"
data += "\r\n"
data += "<html><body>Hello World</body></html>\r\n\r\n"
clientsocket.sendall(data.encode())
clientsocket.shutdown(SHUT_WR)
except KeyboardInterrupt:
print("\nShutting down...\n");
except Exception as exc:
print("Error:\n");
print(exc)
serversocket.close()
print('Access http://localhost:9000')
createServer()
We were also told to build a simple web browser that would connect us to the server we build and it should return "Hello World!", code for it looks like this:
import socket
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(('127.0.0.1', 9000))
cmd = 'GET http://127.0.0.1/romeo.txt HTTP/1.0\r\n\r\n'.encode()
mysock.send(cmd)
while True:
data = mysock.recv(512)
if len(data) < 1:
break
print(data.decode(), end = '')
mysock.close()
First problem is that nowhere in the course there's a mention of romeo.txt, it just popped out of nowhere. They told us to just run the code, but it does nothing. I googled how to launch server so in my command windom I launched it from the directory my server file is located but whenever I try to connect with above web browser (even if I delete "romeo.txt") from code I get error 404.
I know I'm missing something, I know that just launching server from the directory my files are located are not enough, lesson doesn'n explain how to do it but in order to progress in the next lesson I need to do it. Can anyone help me? Sorry if the question is stupid but I'm stuck for two hours already and I have no idea what else can I do.
These two programs are creating sockets.
The first program acts as the server and the second program acts as the client. The first program is waiting for someone to connect to it as in this line serversocket.accept(), while the second program tries to connect to the server as in this line mysock.connect(('127.0.0.1', 9000)).
Your problem is you are not running the server while running the client. The solution is first start the server, keep it running then start the client.
It should work like so, in one cmd / terminal:
python server.py
In other cmd / terminal:
python client.py
Replace server.py and client.py with original file names.
hi i make model server client which works fine and i also create separate GUI which need to two input server IP and port it only check whether server is up or not. But when i run server and then run my GUI and enter server IP and port it display connected on GUI but on server side it throw this error. The Server Client working fine but integration of GUI with server throw below error on server side.
conn.send('Hi'.encode()) # send only takes string BrokenPipeError: [Errno 32] Broken pip
This is server Code:
from socket import *
# Importing all from thread
import threading
# Defining server address and port
host = 'localhost'
port = 52000
data = " "
# Creating socket object
sock = socket()
# Binding socket to a address. bind() takes tuple of host and port.
sock.bind((host, port))
# Listening at the address
sock.listen(5) # 5 denotes the number of clients can queue
def clientthread(conn):
# infinite loop so that function do not terminate and thread do not end.
while True:
# Sending message to connected client
conn.send('Hi'.encode('utf-8')) # send only takes string
data =conn.recv(1024)
print (data.decode())
while True:
# Accepting incoming connections
conn, addr = sock.accept()
# Creating new thread. Calling clientthread function for this function and passing conn as argument.
thread = threading.Thread(target=clientthread, args=(conn,))
thread.start()
conn.close()
sock.close()
This is part of Gui Code which cause problem:
def isOpen(self, ip, port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((ip, int(port)))
data=s.recv(1024)
if data== b'Hi':
print("connected")
return True
except:
print("not connected")
return False
def check_password(self):
self.isOpen('localhost', 52000)
Your problem is simple.
Your client connects to the server
The server is creating a new thread with an infinite loop
The server sends a simple message
The client receives the message
The client closes the connection by default (!!!), since you returned from its method (no more references)
The server tries to receive a message, then proceeds (Error lies here)
Since the connection has been closed by the client, the server cannot send nor receive the next message inside the loop, since it is infinite. That is the cause of the error! Also there is no error handling in case of closing the connection, nor a protocol for closing on each side.
If you need a function that checks whether the server is online or not, you should create a function, (but I'm sure a simple connect is enough), that works like a ping. Example:
Client function:
def isOpen(self, ip, port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((str(ip), int(port)))
s.send("ping".encode('utf-8'))
return s.recv(1024).decode('utf-8') == "pong" # return whether the response match or not
except:
return False # cant connect
Server function:
def clientthread(conn):
while True:
msg = conn.recv(1024).decode('utf-8') #receiving a message
if msg == "ping":
conn.send("pong".encode('utf-8')) # sending the response
conn.close() # closing the connection on both sides
break # since we only need to check whether the server is online, we break
From your previous questions I can tell you have some problems understanding how TCP socket communication works. Please take a moment and read a few articles about how to communicate through sockets. If you don't need live communications (continous data stream, like a video, game server, etc), only login forms for example, please stick with well-known protocols, like HTTP. Creating your own reliable protocol might be a little complicated if you just got into socket programming.
You could use flask for an HTTP back-end.
I am trying to connect to a Bluetooth GPS unit from a Raspberry Pi3 using the socket library in python 3. I am able to connect and get data flowing the first time but if I disconnect and then try reconnecting I get:
[Errno 16] Device or resource busy
I have tried placing the connection in a sub process killing it and recreating it (end goal) and I get the same error. If I close and restart the test program it connects no problem.
Here is a test script based on a demo I found, that opens the connection closes it then tries to reconnect for ever. When I try it I get tick tick tick... until I hit ^c to kill it
import io
import socket
from time import sleep
from bluetooth import *
import sys
class SocketIO(io.RawIOBase):
def __init__(self, sock):
self.sock = sock
def read(self, sz=-1):
if (sz == -1): sz=0x7FFFFFFF
return self.sock.recv(sz)
def seekable(self):
return False
# file: l2capclient.py
# desc: Demo L2CAP client for bluetooth module.
# $Id: l2capclient.py 524 2007-08-15 04:04:52Z albert $
if sys.version < '3':
input = raw_input
if len(sys.argv) < 2:
print("usage: l2capclient.py <addr>")
sys.exit(2)
bt_addr=sys.argv[1]
port = 1
print("trying to connect to %s on PSM 0x%X" % (bt_addr, port))
# Create the client socket
sock=BluetoothSocket( RFCOMM )
sock.connect((bt_addr, port))
fd = SocketIO(sock)
bno = 0
for line in fd:
print(line)
bno +=1
if bno >10:
break
sock.shutdown(socket.SHUT_RDWR)
sock.close()
print("closed")
sock=BluetoothSocket( RFCOMM )
not_connected = True
while not_connected:
try:
sock.connect((bt_addr, port))
not_connected = False
except:
sleep(1)
print("tick")
pass
fd = SocketIO(sock)
try:
for line in fd:
print(line)
except IOError:
pass
sock.close()
The SocketIO class is just for convenience of getting data line by line I have tried it with sock.recv(1024) and got the same results.
I have a similar issue. I send data to an HC-05 bluetooth module from my PC using python sockets and a bluetooth RFCOMM socket. Here are a few things which have seemed to improve the debugging situation working with bluetooth...
If you havent already, make your socket a nonblocking socket, it sends out a flag when something goes wrong instead of crashing the program
Make sure you close the connection properly (it seems that you are doing that though)
Make sure that the GPS has no factory settings that prevent you from connecting instantly again. It could maybe have to do with a factory setting/timeout thing not agreeing with the way you request to connect again, and that error could be due to your code and quite possibly in a factory setting if there are any.
I have trouble connecting to my own socket on localhost.
s.connect(('127.0.0.1', 4458)) (or "localhost") will just take forever,
and eventually timeout with TimeoutError: [Errno 110] Connection timed out
It should open port 4458, another script will then send some chars to it. Both scripts are supposed to run on the same Raspberry Pi, while 'server' one will execute with sudo (to access the GPIOs) and one without, being a chat bot.
I have no trouble running the server on the Pi (with python 3.4.1) and the client on my Laptop (mac, python 3.4.2).
Also it does work in reverse direction, server script on the laptop and client on the Raspberry.
As final test, it works with both, the server and the client on the said macbook.
Just server + client on the Pi does not work.
The program freezes
My shortened code if it helps:
# $ sudo python3 server.py
__author__ = 'luckydonald'
import socket # server
import time # wait for retry
import threading
class Server(threading.Thread):
port = 4458;
QUIT = False
def run(self):
s = socket.socket()
failed = True
print ("Starting Server on Port %d" % (self.port))
while failed:
try:
s.bind(("", self.port))
except Exception as err:
print(err)
print("Port assignment Failed. Retring in 1 second.")
time.sleep(1)
else:
failed = False
print("Success.")
while not self.QUIT:
print("Listening!")
conn, addr = s.accept() # freezes here
print("Got something: %s , %s" %(str(conn), str(addr)))
while not self.QUIT:
result = conn.recv(1)
print("Got result: " + str(result))
server = Server();
server.daemon = True
server.run();
# server.start();
And for the client:
# python3 cilent.py
s = socket.socket()
print("connecting...")
s.connect(("localhost",4458)) # also tried "172.0.0.1" # freezes here
print("connected!")
s.sendall("+".encode("utf-8"))
s.sendall("-".encode("utf-8"))
s.close()
It will result in this:
What I didn't expected was that localhost/127.0.0.1 did not work.
100% package loss
I had a malformatted entry in my hosts file.
You should check for below items
there is an installed internet information services
iis is running
firewall is grants required ports for running the python.exe