From client I am trying to send a txt file to server.
client.py
import socket
TCP_IP = '127.0.0.1'
TCP_PORT = 8340
BUFFER_SIZE = 1024
server_addr = (TCP_IP, TCP_PORT)
c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
c.connect(server_addr)
file = open(r"C:\Users\sakthi\Desktop\Hi.txt",'r')
transfer = file.read(BUFFER_SIZE)
while transfer:
c.send(transfer.encode())
transfer = file.read(1024)
print (s.recv(BUFFER_SIZE).decode())
c.close()
Server.py
import socket
TCP_IP = '127.0.0.1'
TCP_PORT = 8340
BUFFER_SIZE = 1024 # Normally 1024, but we want fast response
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
conn, addr = s.accept()
final = open(r"C:\Users\sakthi\Desktop\final.txt", 'a+')
while 1:
print('Connection address:', addr)
r = conn.recv(BUFFER_SIZE).decode()
if not r:break
final.write(r)
print("received data:", r)
k="file received"
conn.send(k.encode())
conn.close()
Once the file is received, server will send message "file received" to client.
Client will print the message "file received" and close the connection
When I run the code, server.py is not coming out of while loop
while 1:
print('Connection address:', addr)
r = conn.recv(BUFFER_SIZE).decode()
if not r:break
final.write(r)
print("received data:", r)
r = conn.recv(BUFFER_SIZE).decode() keeps listening for new messages, but the client has transferred all messages.
size of the file is 1.14 KB.
Can anybody tell me what's wrong in my program?
I found the solution
Note our statement that recv() blocks until either there is data available to be read or the sender has closed the connection holds only if the socket is in blocking mode. That mode is the default, but we can change a socket to nonblocking mode by calling setblocking() with argument 0.
I have modified the server.py
import socket
TCP_IP = '127.0.0.1'
TCP_PORT = 8340
BUFFER_SIZE = 1024 # Normally 1024, but we want fast response
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
conn, addr = s.accept()
conn.setblocking(0)
final = open(r"C:\Users\sakthi\Desktop\final.txt", 'a+')
while 1:
try:
print('Connection address:', addr)
r = conn.recv(BUFFER_SIZE).decode()
final.write(r)
print("received data:", r)
except:
break
k="file received"
conn.send(k.encode())
conn.close()
Now I am able to receive the file and send message "file received" to client and connection is closed.
non-blocking socket,error is always
http://www.mws.cz/files/PyNet.pdf
Related
I have a simple echo server that echos back whatever it receives. This works well for a single client request.
# echo-server.py
import socket
HOST = "127.0.0.1"
PORT = 65432
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"Connected by {addr}")
while True:
try:
data = conn.recv(1024)
except KeyboardInterrupt:
print ("KeyboardInterrupt exception captured")
exit(0)
conn.sendall(data)
# echo-client.py
import socket
HOST = "127.0.0.1" # The server's hostname or IP address
PORT = 65432 # The port used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.sendall(b"Hello, world")
data = s.recv(1024)
print(f"Received {data!r}")
However, if I finish one client request, and do a second client request, the server no more echoes back. How can I solve this issue?
(base) root#40029e6c3f36:/mnt/pwd# python echo-client.py
Received b'Hello, world'
(base) root#40029e6c3f36:/mnt/pwd# python echo-client.py
On the server side, you need to accept connections in an infinite loop. This should work.
server.py
HOST = "127.0.0.1"
PORT = 65432
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
while True:
conn, addr = s.accept()
print(f"Connected by {addr}")
try:
data = conn.recv(1024)
except KeyboardInterrupt:
print ("KeyboardInterrupt exception captured")
exit(0)
conn.sendall(data)
I have a vpn (using OpenVPN) with mulitple clients connected to a server (at DigitalOcean). The connection is very good and I am able access every client placed behind their respective firewalls when they are connected to their respective routers through ssh. I want to use python scripts to automatically send files from multiple clients to server and vice versa. Here's the code I am using so far:
Server:
#!/usr/bin/env python
import socket
from threading import Thread
from SocketServer import ThreadingMixIn
class ClientThread(Thread):
def __init__(self,ip,port):
Thread.__init__(self)
self.ip = ip
self.port = port
print "[+] New thread started for "+ip+":"+str(port)
def run(self):
while True:
data = conn.recv(2048)
if not data: break
print "received data:", data
conn.send(data) # echo
TCP_IP = '0.0.0.0'
TCP_PORT = 62
BUFFER_SIZE = 1024 # Normally 1024
tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcpsock.bind((TCP_IP, TCP_PORT))
threads = []
while True:
tcpsock.listen(4)
print "Waiting for incoming connections..."
(conn, (ip,port)) = tcpsock.accept()
newthread = ClientThread(ip,port)
newthread.start()
threads.append(newthread)
for t in threads:
t.join()
Client:
#!/usr/bin/env python
import socket
TCP_IP = '10.8.0.1'
TCP_PORT = 62
BUFFER_SIZE = 1024
MESSAGE = "Hello, World!"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(MESSAGE)
data = s.recv(BUFFER_SIZE)
s.close()
print "received data:", data
The problem is im not able to get a connection. The server only prints "Waiting for incoming connections..." and the client does not seem to find its way to the server. Is there anyone who can take a look at this and give me some feedback on wath I am doing wrong?
Can you try something like this?
import socket
from threading import Thread
class ClientThread(Thread):
def __init__(self,ip,port):
Thread.__init__(self)
self.ip = ip
self.port = port
print "[+] New thread started for "+ip+":"+str(port)
def run(self):
while True:
data = conn.recv(2048)
if not data: break
print "received data:", data
conn.send(b"<Server> Got your data. Send some more\n")
TCP_IP = '0.0.0.0'
TCP_PORT = 62
BUFFER_SIZE = 1024 # Normally 1024
threads = []
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(("0.0.0.0", 5000))
server_socket.listen(10)
read_sockets, write_sockets, error_sockets = select.select([server_socket], [], [])
while True:
print "Waiting for incoming connections..."
for sock in read_sockets:
(conn, (ip,port)) = server_socket.accept()
newthread = ClientThread(ip,port)
newthread.start()
threads.append(newthread)
for t in threads:
t.join()
Now the client will have something like below:
import socket, select, sys
TCP_IP = '0.0.0.0'
TCP_PORT = 62
BUFFER_SIZE = 1024
MESSAGE = "Hello, Server. Are you ready?\n"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, 5000))
s.send(MESSAGE)
socket_list = [sys.stdin, s]
while 1:
read_sockets, write_sockets, error_sockets = select.select(socket_list, [], [])
for sock in read_sockets:
# incoming message from remote server
if sock == s:
data = sock.recv(4096)
if not data:
print('\nDisconnected from server')
sys.exit()
else:
sys.stdout.write("\n")
message = data.decode()
sys.stdout.write(message)
sys.stdout.write('<Me> ')
sys.stdout.flush()
else:
msg = sys.stdin.readline()
s.send(bytes(msg))
sys.stdout.write('<Me> ')
sys.stdout.flush()
The output is as below:
For server -
Waiting for incoming connections...
[+] New thread started for 127.0.0.1:52661
received data: Hello, World!
Waiting for incoming connections...
received data: Hi!
received data: How are you?
For client -
<Server> Got your data. Send some more
<Me> Hi!
<Me>
<Server> Got your data. Send some more
<Me> How are you?
<Me>
<Server> Got your data. Send me more
<Me>
In case you want to have an open connection between the client and server, just keep the client open in an infinite while loop and you can have some message handling at the server end as well. If you need that I can edit the answer accordingly. Hope this helps.
This question has been asked before but none of the answers was helpful in my case. The problem seems very simple. I am running a TCP server on an raspberry pi and try to connect to it from another machine. I have a custom class receiver that pipes sensor data to this script.
When I close the program running on the other machine (the socket is 'shutdown(2)'d and then 'close()'d), I cannot reconnect to that same port anymore. I tried to alternate between two sockets (1180 and 1181) but this did not work. When I connect over a port once, it is gone forever until I restart the TCP server. I tried restarting the script (with executl()) but that did not resolve my problem. I am telling the socket that it should re-use addresses but to no avail.
What I could do is use more ports but that would require opening more ports on the RPi which I would like to avoid (there must be another way to solve this).
import socket
from receiver import receiver
import pickle
import time
import os
import sys
TCP_IP = ''
TCP_PORT = 1180
BUFFER_SIZE = 1024
print 'Script started'
while(1):
try:
print 'While begin'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
print 'Socket created'
s.settimeout(5)
print 'Trying to bind'
s.bind((TCP_IP, TCP_PORT))
print 'bound to', (TCP_IP, TCP_PORT)
s.listen(1)
print 'listening for connection'
conn, addr = s.accept()
print 'accepted incoming connection'
s.settimeout(5)
r = receiver()
print 'Connection address:', addr
for cur in r:
#print "sending data:", cur
print len(cur.tostring())
conn.send(cur.tostring()) # echo
except Exception as e:
r.running = False
print e
if TCP_PORT == 1181:
TCP_PORT = 1180
else:
TCP_PORT = 1181
time.sleep(1)
print 'sleeping 1sec'
Your server socket is still in use, so you cannot open more than one server socket for each port. But why should one. Just reuse the same socket for all connections (that's what server sockets made for):
import socket
from receiver import receiver
import logging
TCP_IP = ''
TCP_PORT = 1180
BUFFER_SIZE = 1024
print 'Script started'
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
print 'Trying to bind'
server.bind((TCP_IP, TCP_PORT))
print 'bound to', (TCP_IP, TCP_PORT)
server.listen(1)
print 'listening for connection'
while True:
try:
conn, addr = server.accept()
print 'accepted incoming connection'
print 'Connection address:', addr
for cur in receiver():
data = cur.tostring()
#print "sending data:", cur
print len(data)
conn.sendall(data) # echo
except Exception:
logging.exception("processing request")
Im writing a simple socket program to receive some data and reverse the contents.
When I pass the reversed contents its not being sent..
Server
import socket
s = socket.socket()
host = socket.gethostname()
port = 1234
s.bind((host, port))
s.listen(5)
while True:
c, addr = s.accept()
print('Got connection from', addr)
print('Received message == ',c.recv(50))
s = c.recv(50)[::-1]
c.send(s)
c.close()
client
import socket
from time import sleep
s = socket.socket()
host = socket.gethostname()
port = 1234
s.connect((host, port))
print "Sending data"
s.sendall("Hello!! How are you")
print(s.recv(1024))
The problem is two lines in your server
Your server calls recv() inside a print statement. This empties the buffer. Then you call recv() again, but it is already emptied by the previous statement and so it then blocks.
You need to call recv() and store that in s. Then use s everywhere else.
Try this for your server:
import socket
s = socket.socket()
host = socket.gethostname()
port = 1234
s.bind((host, port))
s.listen(5)
while True:
c, addr = s.accept()
print('Got connection from', addr)
s = c.recv(50)
print('Received message == ',s)
c.send(s)
c.close()
I have a remote device which sends text data on TCP 5005 port. The code below is to get the data from remote device but its throwing an error. Can someone please help on this.
conn, addr = s.accept()
File "C:\Python26\lib\socket.py", line 197, in accept
sock, addr = self._sock.accept()
socket.error: [Errno 10022] An invalid argument was supplied"
Code:
#!/usr/bin/env python
import socket
TCP_IP = '192.168.0.12'
TCP_PORT = 5005
BUFFER_SIZE = 1024 # Normally 1024, but we want fast response
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
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()