client-server chat python error - python

I'm trying the following client and server chat program. Although I get an error whenever I try to run the server program, when the client program runs it stays on a blank screen not allowing me to type anything. I've tried running server first and running client first and I get the same results. I can't read the error from the server program because it flashes the error and closes the window. Here is my code:
server:
#server
import socket
import time
HOST = ''
PORT = 8065
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((HOST,PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
data = conn.recv(1024)
if not data: break
conn.sendall(data)
conn.close()
client:
#client
import socket
import time
HOST = "localhost"
PORT = 8065
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect((HOST,PORT))
s.sendall('Helloworld')
data = s.recv(1024)
s.close()
print 'Recieved', repr(data)

Im not an expert but I was able to make your examples work by changing the socket from datagram to stream connection, and then encoding message being sent because strings aren't supported (although this might not effect you since I think that change was made in Python 3...I'm not 100% sure).
I believe the main issue is that you're trying to listen() but SOCK_DGRAM (UDP) doesn't support listen(), you just bind and go from there, whereas SOCK_STREAM (TCP) uses connections.
If you're just trying to get the program going, use the below code, unless there is a specific reason you'd like to use SOCK_DGRAM.
The code is below:
client
#client
import socket
import time
HOST = "localhost"
PORT = 8065
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST,PORT))
test = 'Helloworld'
s.sendall(test.encode())
data = s.recv(1024)
s.close()
print 'Recieved', repr(data)
server
#server
import socket
import time
HOST = ''
PORT = 8065
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST,PORT))
s.listen(1)
conn, addr = s.accept()
print ('Connected by', addr)
while 1:
data = conn.recv(1024)
if not data: break
conn.sendall(data)
conn.close()

Related

weird movement socket based programming [duplicate]

I copied the echo server example from the python documentation and it's working fine. But when I edit the code, so it wont send the data back to the client, the socket.recv() method doesn't return when it's called the second time.
import socket
HOST = ''
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print('Connected by', addr)
while True:
data = conn.recv(1024)
if not data: break
conn.sendall(b'ok')
conn.close()
In the original version from the python documentation the while loop is slightly different:
while True:
data = conn.recv(1024)
if not data: break
conn.sendall(data)
Client's code:
import socket
HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
data = s.recv(1024)
s.close()
print('Received', repr(data))
TCP sockets are streams of data. There is no one-to-one correlation between send calls on one side and receive calls on the other. There is a higher level correlation based on the protocol you implement. In the original code, the rule was that the server would send exactly what it received until the client closed the incoming side of the connection. Then the server closed the socket.
With your change, the rules changed. Now the server keeps receiving and discarding data until the client closes the incoming side of the connection. Then the server sends "ok" and closes the socket.
A client using the first rule hangs because its expecting data before it closes the socket. If it wants to work with this new server rule, it has to close its outgoing side of the socket to tell the server its done, and then it can get the return data.
I've updated the client and server to shutdown parts of the connection and also have the client do multiple recv's in case the incoming data is fragmented. Less complete implementations seem to work for small payloads because you are unlikely to get fragmentation, but break horribly in real production code.
server
import socket
HOST = ''
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print('Connected by', addr)
while True:
data = conn.recv(1024)
if not data: break
conn.sendall(b'ok')
conn.shutdown(socket.SHUT_WR)
conn.close()
client
import socket
HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
s.shutdown(socket.SHUT_WR)
data = b''
while True:
buf = s.recv(1024)
if not buf:
break
data += buf
s.close()
print('Received', repr(data))
The number of receive and send operations have to match because they are blocking. This is the flow diagram for your code:
Server listen
Client connect
Server receive (this waits until a message arrives at the server) [1]
Client send 'Hello world' (received by [1])
Server receive (because there was data received) [2]
Client receive [3]
Because the server and the client are blocked now, no program can continue any further.
The fix would be to remove the client's receive call because you removed the server's send call.

Can't get client to connect to server

I'm just very confused still about the basic socket process. Tried multiple ways to try and get the socket to connect but it keeps refusing.
client code- socket_client.py
import socket
host = socket.gethostname()
port = 8080
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((host,port))
res = client.send (b' testing data send...')
client.close()
server code- server_client.py
import socket
host = socket.gethostname()
port = 8080
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
server.listen(10)
x=0
server_data = []
while True:
conn, addr = server.accept()
data = conn.recv(4096).decode()
x += 1
print ('Servicing client at %s'%addr[0])
server_data = client.recv(4096)
client_close()
server.close()
You have some problems in your server. You read from the connection but never use it, and you do client.recv when there is no variable client. This works:
import socket
host = socket.gethostname()
port = 8080
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
server.listen(10)
x=0
server_data = []
while True:
conn, addr = server.accept()
x += 1
print ('Servicing client at %s'%addr[0])
data = conn.recv(4096).decode()
print( "Received", data )
conn.close()
server.close()
Do remember that Python has a SocketServer module that can make some of this easier. If you need to get fancier, there are few modules better than Twisted at this kind of thing.
ALSO remember that the server must be running before you start the client. Someone has to be listening, otherwise the connection is rejected.

Getting error non-blocking (10035) error when trying to connect to server

I am trying to simply send a list from one computer to another.
I have my server set up on one computer, where the IP address is 192.168.0.101
The code for the server:
import socket
import pickle
import time
import errno
HEADERSIZE = 20
HOST = socket.gethostbyname(socket.gethostname())
PORT = 65432
print(HOST)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(10)
while True:
conn, adrs = s.accept()
print(f"Connection with {adrs} has been established")
conn.setblocking(1)
try:
data = conn.recv(HEADERSIZE)
if not data:
print("connection closed")
conn.close()
break
else:
print("Received %d bytes: '%s'" % (len(data), pickle.loads(data)))
except socket.error as e:
if e.args[0] == errno.EWOULDBLOCK:
print('EWOULDBLOCK')
time.sleep(1) # short delay, no tight loops
else:
print(e)
break
The client is on another computer. The code:
import socket
import pickle
HOST = '192.168.0.101'
PORT = 65432
def send_data(list):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(10)
print(".")
print(s.connect_ex((HOST, PORT)))
print(".")
data = pickle.dumps(list)
print(len(data))
s.send(data)
s.close()
send_data([1,1,1])
The outputted error number of connect_ex is 10035. I read a lot about the error, but all I found was about the server side. To me, it looks like the problem is with the client and that it is unable to make a connection to 192.168.0.101. But then, I don't understand why the error I get is about non-blocking.
What is it that I am doing wrong that I am unable to send data?
First of all, how user207421 suggested, change the timeout to a longer duration.
Also, as stated here Socket Programming in Python raising error socket.error:< [Errno 10060] A connection attempt failed I was trying to run my server and connect to a private IP address.
The fix is: on the server side, in the s.bind, to leave the host part empty
HOST = ''
PORT = 65432
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
And on the client side, use the public IP of the PC where the server is running (I got it from ip4.me)
HOST = 'THE PUBLIC IP' #not going to write it
PORT = 65432
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, PORT))

Python Socket Programming - ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it

I'm doing an assignment regarding socket programming in python using a client and server. I'm currently on windows 10. Before getting into the little details of the assignment, I've been trying to simply connect the server and client.
Every time I try to run the client file, I would get this error
File "tcpclient.py", line 9, in <module>
s.connect((host, port))
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
I have opened the firewall ports and still nothing. I've tried replacing host with '', 0.0.0.0, socket.gethostname() in both the client and server file but the error still persists. I've even tried different port numbers but it made no difference. I've tried running this code on Ubuntu and Max and I get the same error - connection refused. I've been researching for many solutions but I still have yet to find one that works. Any help would be greatly appreciated!
Note: this code was taken online but it's essentially the basis of what I need to accomplish.
tcpclient.py
import socket
host = '127.0.0.1'
port = 80
buffer_size = 1024
text = "Hello, World!"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.send(text)
data = s.recv(buffer_size)
s.close()
print("received data:", data)
tcpserver.py
import socket
host = '127.0.0.1'
port = 80
buffer_size = 20
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(1)
conn, addr = s.accept()
print 'Connection address:', addr
while 1:
data = conn.recv(buffer_size)
if not data: break
print("received data:", data)
conn.send(data) # echo
conn.close()
Just use a different port. Both the client and server should have the same port and host if not it won't work. Make sure to run the server before the client script.
For client.py
import socket
host = '127.0.0.1'
port = 9879
buffer_size = 1024
text = "Hello, World!"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
text = text.encode('utf-8')
s.send(text)
data = s.recv(buffer_size)
s.close()
print("received data:", data)
For server.py
import socket
mysocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
buffer_size = 1024
text = "Hello, World!"
mysocket.bind(('127.0.0.1', 9879))
mysocket.listen(5)
(client, (ip,port)) = mysocket.accept()
print(client, port)
client.send(b"knock knock knock, I'm the server")
data = client.recv(buffer_size)
print(data.decode())
mysocket.close()
Just change the port number and it will work and if you are in python3 then you will have to encode and decode as socket recieves and sends only binary strings.
I have succeed in my server!
My server python script is below:
import socket
host='0.0.0.0'
port=2345
s=socket.socket()
s.bind((host,port))
s.listen(2)
while True:
conn,addr=s.accept()
print("Connected by",addr)
data=conn.recv(1024)
print("received data:",data)
conn.send(data)
conn.close()
My Client python script is below:
import socket
s=socket.socket()
host="xx.xx.xx.xx" #This is your Server IP!
port=2345
s.connect((host,port))
s.send(b"hello")
rece=s.recv(1024)
print("Received",rece)
s.close()
There is two points needed to be careful in the script:
1.The host of the Server must is
'0.0.0.0'
So that the python script could user all interfaces in the server
2.I have find the question's error through the prompt:
TypeError: a bytes-like object is required, not 'str'
It means every string message in the 'send' method need to convert to 'bytes-like object',So the correct is
s.send(b"hello")
It is important that this is b'hello' not is 'hello'
I was following a tutorial that used threading to start the server. Once I removed the threading then I was able to connect to it.

Connecting client and server in python the code below dont give output make browser busy

This code is not giving output it just makes the browser busy. Any idea why?
import socket
s = socket.socket()
host = socket.gethostname()
port = 12345
s.connect(('127.0.0.1', port))
print (s.recv(1024))
s.close
import socket
s=socket.socket()
host = socket.gethostname()
port = 12345
s.bind(('127.0.0.1', port))
s.listen(5)
while True:
c,addr = s.accept()
print ('Got connection from', addr)
c.send('Thank you for connecting')
c.close()
client program:
import socket
f=open("hello.txt","r").read()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = 12345
s.connect(('127.0.0.1', port))
s.sendall(str.encode(f))
print (s.recv(1024).decode('ascii'))
s.close()
server program:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print ("Socket successfully created")
port = 12345
s.bind(('', port))
print ("socket binded to %s" %(port))
f=open("hi.txt","r").read()
s.listen(5)
print ("socket is listening")
while True:
c, addr = s.accept()
print ('Got connection from', addr)
print (c.recv(1024).decode('ascii'))
c.sendall(str.encode(f))
c.close()
server output:
Socket successfully created
socket binded to 12345
socket is listening
Got connection from ('127.0.0.1', 51630)
helloooooo
client output:
hiiiii
Open the two programs in seperate shells.
Run server program first then client program.
Dont close the server program before running client program.
Create two files one for server and one for client.
Read the data from those files and send it.
While receiving the data decode it and print it.
You can send entire data from files or just a single line it depends on you.
To know more about reading,writing and creating files you can refer https://docs.python.org/release/3.6.5/tutorial/inputoutput.html#reading-and-writing-files
Let me know if it worked :)

Categories