Basic Python TCP Socket Server & Client - python

My first question here, please be gentle :) I'm trying to setup a basic Python (2.7) TCP socket server that is multithreaded (I haven't got to the multithreaded part yet), and a client.
Here is the server:
# Basic TCP socket server
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = ''
port = 8888
s.bind((host, port))
s.listen(5)
while True:
c, addr = s.accept()
print("Connected to %s" % addr)
c.send("Hello socket")
c.close()
And here is the client:
# Basic TCP socket client
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = '127.0.0.1'
port = 8888
s.connect((host, port))
print s.recv(1024)
s.close()
When I run the server it seems to execute without errors, but when I run the client to connect, I don't see the message that should be printed out to my terminal window where server is running. Here is the error (as #Rawing pointed out):
Traceback (most recent call last): File "server.py", line 19, in
print("Connected to %s" % addr) TypeError: not all arguments converted during string formatting
As far as making the server multithreaded, I need to read up on that but any suggestions are welcome.
Thank You.

You have two problems in your code
Your use of the string-formatting operator % is incorrect in your server program. If you pass a tuple to % (and addr is a tuple), then each item in the tuple must match one formatting directive. This is why your server program is failing.
print("Connected to %s" % str(addr))
In both programs, you mention, but do not invoke, socket.close. Try these in the appropriate locations:
s.close()
c.close()

A simple implementation of a TCP server in python 3 (If you are willing to use it instead of 2.7)
Server:
import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
data = self.rfile.readline() # Receive data from client
self.wfile.write(new_data) # Send data to client
if __name__ == "__main__":
with socketserver.UDPServer((HOST, PORT), MyUDPHandler) as server:
server.serve_forever()
Client:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((HOST, PORT)) # Connect
sock.sendall(bytes(data + "\n", "utf-8")) # Send data
received = str(sock.recv(1024), "utf-8") # Receive data synchronically

bind the server to an ip, eg: host='127.0.0.1, and it should work.
Update: I'm totally wrong. I fixed a few things in your scripts and assumed that was the issue, but it's not - as the reply below states, binding to ('', ) is perfectly valid.
Looks like your socket code is perfectly good, but falls over the print statement. I fixed it with print("Connected to {}".format(addr))

Related

How to send requests to another computer with python

Basically I have a chatroom which I'm going to turn into a network (I know it doesn't sound like it makes a lot of sense) but basically I was wondering if I could have a python script capture all outgoing requests on a computer and instead send it to another computer (c2). I then want c2 to make the request on it's own. This is a watered down explanation of what I'm doing but any help will be great!
Firstly, you can set up a remote machine and get its IP address. On the remote machine you can set up this code:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('*CHANGE TO SERVER IP*', portnumber)
print("Starting on %s port %s" % server_address)
sock.bind(server_address)
sock.listen(1)
while True:
connection, client_address = sock.accept()
try:
data = connection.recv(999)
# You have received the data, do what you want with it.
except:
connection.close()
And on the client machine:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('*INSERT SERVER IP*', portnumber)
print('Connecting to %s port %s' % server_address)
while True:
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(server_address)
message=input('Message: ')
if message=='quit':
break
sock.sendall(message)
except:
break
sock.close()
The server side code also works as client side for receiving information.

TCP SocketServer only accepts connections without AF_INET and SOCK_DGRAM passed into client

I am setting up a basic TCP server for receiving local connections. I already have client applications with sockets constructed in the following way sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM). I need the client to be able to connect with these parameters even if they aren't required. Something about my very simple server does not allow this connection if those two params are passed in.
I have made sure that the IP and port are available on my computer. I have successfully connected a UDP client to a similar Handler with these parameters passed in. I have gotten a successful TCP connection by just constructing the client as sock = socket.socket() without parameters.
Server File:
class TCPHandler(SocketServer.BaseRequestHandler):
def handle(self):
self.data = self.request.recv(1024).strip()
self.request.sendall(self.data.upper())
...
#(in main)
server = SocketServer.TCPServer((HOST,PORT), TCPHandler)
print "TCP Server Started"
Client File:
try:
#sock = socket.socket()
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(3.0)
print "Attempting to TCP connection"
PORT = 53140
sock.connect((HOST, PORT))
print "Connected to TCP"
sock.sendall(data + "\n")
received = sock.recv(1024)
sock.close()
except Exception as e:
print e
If I run the code as pasted I get a "Connection Refused" error. If I used the commented line instead, the TCP connection works.

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.

Python server programming

I am trying a little client server project to get me into network programming but I seem to have got stuck at the first hurdle. I cant seem to get past getting the first line of data only even if its a new connection.
#!/usr/bin/python
import socket
s = socket.socket()
host = '192.168.0.233' # Test Server
port = 7777
s.bind((host, port))
s.listen(5)
while True:
c, addr = s.accept()
print 'Got connection from', addr
data = c.recv(2048)
print(data)
If I telnet to the host running the server, the connection opens fine and I see on the server Got connection from addr, but I also only see the first line of data when I sent 4 lines of data,
I thought because its in a loop it should now always be looking for data?
I know im doing something wrong but unsure what.
Im using Python 2.6.6
recv needs to be in a loop too, at the moment your code is receiving some data and then waiting for a new connection.
https://docs.python.org/2/library/socket.html#example has an example of socket.recv in a loop.
Try this:
#!/usr/bin/python
import socket
import threading
def listenForClients(sock):
while True:
client, address = sock.accept()
client.settimeout(5)
threading.Thread( target = listenToClient, args = (client,address) ).start()
def listenToClient(client, address):
size = 2048
while True:
try:
data = client.recv(size)
if data:
response = "Got connection"
client.send(response)
else:
raise error('Client disconnected')
except:
client.close()
return False
def main(host, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((host, port))
sock.listen(5)
listenForClients(sock)
if __name__ == "__main__":
main('192.168.0.233',7777)
Here I use a thread for each client. The problem that you have with having Socket.accept() in the loop is that it blocks meaning that concurrent access won't work and you'll only be able to talk to one client at a time.
Try running it in the background and sending it messages with:
#!/usr/bin/python
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('192.168.0.233',7777))
vwhile True:
data = raw_input("enter a message: ")
sock.send(data)
print sock.recv(2048)

Sending string via socket (python)

I have two scripts, Server.py and Client.py.
I have two objectives in mind:
To be able to send data again and again to server from client.
To be able to send data from Server to client.
here is my Server.py :
import socket
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "192.168.1.3"
port = 8000
print (host)
print (port)
serversocket.bind((host, port))
serversocket.listen(5)
print ('server started and listening')
while 1:
(clientsocket, address) = serversocket.accept()
print ("connection found!")
data = clientsocket.recv(1024).decode()
print (data)
r='REceieve'
clientsocket.send(r.encode())
and here is my client :
#! /usr/bin/python3
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host ="192.168.1.3"
port =8000
s.connect((host,port))
def ts(str):
s.send('e'.encode())
data = ''
data = s.recv(1024).decode()
print (data)
while 2:
r = input('enter')
ts(s)
s.close ()
The function works for the first time ('e' goes to the server and I get return message back), but how do I make it happen over and over again (something like a chat application) ?
The problem starts after the first time. The messages don't go after the first time.
what am I doing wrong?
I am new with python, so please be a little elaborate, and if you can, please give the source code of the whole thing.
import socket
from threading import *
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "192.168.1.3"
port = 8000
print (host)
print (port)
serversocket.bind((host, port))
class client(Thread):
def __init__(self, socket, address):
Thread.__init__(self)
self.sock = socket
self.addr = address
self.start()
def run(self):
while 1:
print('Client sent:', self.sock.recv(1024).decode())
self.sock.send(b'Oi you sent something to me')
serversocket.listen(5)
print ('server started and listening')
while 1:
clientsocket, address = serversocket.accept()
client(clientsocket, address)
This is a very VERY simple design for how you could solve it.
First of all, you need to either accept the client (server side) before going into your while 1 loop because in every loop you accept a new client, or you do as i describe, you toss the client into a separate thread which you handle on his own from now on.
client.py
import socket
s = socket.socket()
s.connect(('127.0.0.1',12345))
while True:
str = raw_input("S: ")
s.send(str.encode());
if(str == "Bye" or str == "bye"):
break
print "N:",s.recv(1024).decode()
s.close()
server.py
import socket
s = socket.socket()
port = 12345
s.bind(('', port))
s.listen(5)
c, addr = s.accept()
print "Socket Up and running with a connection from",addr
while True:
rcvdData = c.recv(1024).decode()
print "S:",rcvdData
sendData = raw_input("N: ")
c.send(sendData.encode())
if(sendData == "Bye" or sendData == "bye"):
break
c.close()
This should be the code for a small prototype for the chatting app you wanted.
Run both of them in separate terminals but then just check for the ports.
This piece of code is incorrect.
while 1:
(clientsocket, address) = serversocket.accept()
print ("connection found!")
data = clientsocket.recv(1024).decode()
print (data)
r='REceieve'
clientsocket.send(r.encode())
The call on accept() on the serversocket blocks until there's a client connection. When you first connect to the server from the client, it accepts the connection and receives data. However, when it enters the loop again, it is waiting for another connection and thus blocks as there are no other clients that are trying to connect.
That's the reason the recv works correct only the first time. What you should do is find out how you can handle the communication with a client that has been accepted - maybe by creating a new Thread to handle communication with that client and continue accepting new clients in the loop, handling them in the same way.
Tip: If you want to work on creating your own chat application, you should look at a networking engine like Twisted. It will help you understand the whole concept better too.

Categories