Why does socket close when sending message over socket? - python

Why does my connection stop after 3 print statements if I have the conn.send() line? If that line is commented out, the connection stays open indefinitely. It is hitting the exception for some reason, but I don't know why and I am inexperienced with python.
server.py:
import random
import signal
import socket
import struct
import sys
import time
PORT = 1234
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', PORT))
s.listen(1)
print("Server started on port %u" % PORT)
try:
while True:
(conn, addr) = s.accept()
conn.setblocking(0)
print("Client connected: %s:%d" % addr)
while True:
print "hey"
conn.send("random")
time.sleep(1)
except:
s.close()
print "exception"
client.py:
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 1234 # Reserve a port for your service.
s.connect((host, port))
print s.recv(1024)
s.close

The reason for this behavior is the socket is actually closed after the clients first recv(), your server just doesn't realize it until the third attempt at send(). Calling close() in your client didn't change anything because previously the program was terminating which closed the socket anyway. This thread explains why this is very likely what's happening. To test this theory, you could try having the client sleep (or select) and print more recv() calls, before closing the socket.

Related

Keep Client connection alive

I am a beginner in python socket programming. My question is, I have a TCP server in listen mode at that time client will send data to the server. But when my TCP server is unavailable at that I want a client to go and check for connection every time (something like try exception method with while loop).
I have tried tricks but that didn't work out, it gives o/p like connection refused when my TCP server is unavailable. Below is my code help me with same.
# client.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 2195
s.connect((host, 2195))
while 1:
try:
print "Try loop"
s.sendall("Welcome to Python\r\n")
print "Try loop2"
time.sleep(5)
except:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.close()
I have tried many solutions but below code works for me.
client.py
import socket
import time
while True:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)
host = socket.gethostname()
port = 2195
try:
s.connect((host , port))
s.sendall("Welcome to Python\r\n")
except:
print "Error"
time.sleep(5)
s.close()

How to send a message from client to server in python

I'm reading two programs in Python 2.7.10 with client and server. How can I modify these programs in order to send a message from client to server?
server.py:
#!/usr/bin/python # This is server.py file
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 12345 # Reserve a port for your service.
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
while True:
c, addr = s.accept() # Establish connection with client.
print 'Got connection from', addr
c.send('Thank you for connecting')
c.close() # Close the connection
client.py:
#!/usr/bin/python # This is client.py file
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 80 # Reserve a port for your service.
s.connect((host, port))
print s.recv(1024)
s.close # Close the socket when done
TCP sockets are bi-directional. So, after connection, there is no difference between server and client, you only have two ends of a stream:
import socket # Import socket module
s = socket.socket() # Create a socket object
s.bind(('0.0.0.0', 12345)) # Bind to the port
s.listen(5) # Now wait for client connection.
while True:
c, addr = s.accept() # Establish connection with client.
print 'Got connection from', addr
print c.recv(1024)
c.close() # Close the connection
and the client:
import socket # Import socket module
s = socket.socket() # Create a socket object
s.connect(('localhost', 12345))
s.sendall('Here I am!')
s.close() # Close the socket when done
The above answer throws an error: TypeError: a bytes-like object is required, not 'str'
However, the following code worked for me:
server.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = 3125
s.bind(('0.0.0.0', port))
print ('Socket binded to port 3125')
s.listen(3)
print ('socket is listening')
while True:
c, addr = s.accept()
print ('Got connection from ', addr)
print (c.recv(1024))
c.close()
client.py:
import socket
s = socket.socket()
port = 3125
s.connect(('localhost', port))
z = 'Your string'
s.sendall(z.encode())
s.close()

Python socket allow only one connection, but disconnect on new, not refuse

In python, you can define maximum number of socket connections by parameter of listen() function... for example:
serversocket = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind((socket.gethostname(), 80))
serversocket.listen(1) // allow only 1 connection
But the problem is that when second client wants to connect, connection is being refused. And I would like to disconnect the old user and connect the new one. Could anybody help me with that?
Probably an answer:
I am posting it in question as it is probable answer (I didn't have time to check it)
serversocket = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind((socket.gethostname(), 80))
serversocket.listen(10) // allow 10 connections, but disconnect previous later
someone_connected = 0
while 1:
(clientsocket, address) = serversocket.accept()
if(someone_connected) someone_connected.close()
someone_connected = clientsocket
I am not sure that I fully understand you question, but I think the following example can meet your requirement. the server can disconnect the old user and serve the new one.
the sever side:
#!/usr/bin/env python
import socket
import multiprocessing
HOST = '127.0.0.1'
PORT = 50007
# you can do your real staff in handler
def handler(conn, addr):
try:
print 'processing...'
while 1:
data = conn.recv(1024)
if not data:
break
print data
conn.sendall(data)
conn.close()
print 'processing done'
except:
pass
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(5)
processes = []
while True:
conn, addr = s.accept()
print conn, addr
[p.terminate() for p in processes] # to disconnect the old connection
# start process newer connection and save it for next kill
p = multiprocessing.Process(target=handler, args=(conn, addr))
processes = [p]
p.start()
newest_conn = conn # this is the newest connection object, if you need it
For test, the client side:
#!/usr/bin/env python
import socket
import time
import multiprocessing
HOST = '127.0.0.1'
PORT = 50007
def client():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
time.sleep(0.1)
try:
for n in range(20):
s.send(str(n))
data = s.recv(1024)
print data
time.sleep(0.5)
s.send('')
s.close()
except:
pass
if __name__ == "__main__":
for i in range(5):
print 'user %i connect' %i
p = multiprocessing.Process(target=client)
p.start() # simulate a new user start connect
time.sleep(3)
Try it :-)
You have a wrong assumption built into your question - the single argument to socket listen() is not the "number of connections", but a backlog - number of pending, but not yet accepted client connections the kernel holds for you for a while.
Your problem then seems to be that you have accepted one connection, and reading/writing to it in a loop, and not calling accept() again. The kernel holds the request for any new client connection for some timeout, then notifies the client that the server is not accepting it.
You want to look into select() functionality, as suggested in the comments.

Python Socket Error "Only one usage of each socket address is normally permitted"

I have a basic server and client that prints a message on the server when a client connects, and then prints a message on the client saying "Thanks for connecting." But when I try to run the server again(after closing it), I get "error: Only one usage of each socket address is normally permitted"(Not exact). And when I change the port again it works.
#Server
import socket
s = socket.socket()
host = socket.gethostname()
port = 12345
s.bind((host, port))
s.listen(5)
while True:
c, addr = s.accept()
print 'Got connection from', addr
c.send('Thank you for connecting')
c.close()
.
#Client
import socket
s = socket.socket()
host = socket.gethostname()
port = 12345
s.connect((host, port))
print s.recv(1024)
s.close
If I change the last two lines of code for the server to
break
c.close()
it works but closes the server.
How can I keep the server up after the client disconnects without having to change the port each time?
You want to set the socket option SO_REUSEADDR:
Example:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)

Restart socket server in python

I've wrote a simple socket server in python (OS X). I want the server to restart when a client terminate the communication, so that the client can do a reconnect to the server. Look at the code below, what do i have to do at the "lost contact" IF? I'm completely new to Python.
Here is the code:
import socket
import os
s = socket.socket()
host = socket.gethostname()
port = 5555
os.system('clear')
print 'Server started'
print 'Waiting'
s.bind((host, port))
s.listen(5)
c, addr = s.accept()
print 'Contact', addr
while True:
msg = c.recv(1024)
if not msg:
s.close
print "Lost contact"
exit ()
else:
print msg
I dont know if you ever found your answer but i found this when i was searching for the same problem. I was trying to reset the socket on the server so that I could connect to the next client so i tried using socket.close() and then reinitializing the whole socket, but you actually don't need to do anything on the server side, just use socket.close() on the client side and another client can connect without screwing up the server (I realize this probably doesnt help you much now but in case anyone else did what i did I wanted them to know)
If I got you, you want to listen again when client gets disconnected so this should do its job:
import socket
import os
s = socket.socket()
host = socket.gethostname()
port = 5555
os.system('clear')
print 'Server started'
print 'Waiting'
def server():
s.bind((host, port))
s.listen(5)
c, addr = s.accept()
print 'Contact', addr
while True:
msg = c.recv(1024)
if not msg:
s.close
print "Restarting..."
server()
else:
print msg

Categories

Resources