I have a program interacting with two servers (all on localhost), which essentially forwards data from one server to the other.
I am trying to create a scenario where the server sending the initial data will close its connection to the middle-program because the server receiving the data has a very slow connection to the middle-program. The buffers of the middle-program should get filled, and it shouldn't be able to receive any data from the server sending data. As a result of this inactivity, the server sending data should timeout and close the connection, resulting in an in-complete data transfer.
I am trying to do it in the following way:
Program at server sending the data
import socket
interval_sec = 3
TCP_KEEPALIVE = 0x10
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
sock.setsockopt(socket.IPPROTO_TCP, TCP_KEEPALIVE, interval_sec)
sock.bind(('', 9000))
sock.listen(5)
while True:
conn, addr = sock.accept()
f = open('test.txt', 'r')
file_data = f.read(1024)
while (file_data):
conn.send(file_data)
file_data = f.read(1024)
f.close()
print "sent"
Middle program forwarding the data
import socket
import select
import time
import struct
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
recv_timeout = 2
sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, struct.pack('LL', recv_timeout, 0))
total_data=[]
total_sent=0;
data=0;
sock.connect(('localhost', 9000))
sock2.connect(('localhost', 8001))
sock2.setblocking(0)
sock.setblocking(0)
j=0
while 1:
read, write, errors = select.select([sock], [sock2], [], 2)
if read:
data=sock.recv(1024, socket.MSG_DONTWAIT)
total_data.append(data)
#time.sleep(10)
if write:
if data:
try:
data_sent=sock2.send(data, socket.MSG_DONTWAIT)
total_sent+=data_sent
data=data[data_sent:]
print data_sent
except socket.error, e:
if e.errno != errno.EAGAIN:
raise e
else:
print "Not writable"
Program at server receiving the data
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('', 8001))
sock.listen(5)
while True:
conn, addr = sock.accept()
with open('received_file', 'wb') as f:
while True:
file_data = conn.recv(100)
print('receiving data...')
if not file_data:
break
f.write(file_data)
f.close()
conn.close()
The problem I'm facing is that, the middle-program's sockets are blocking although they should be acting as non-blocking.
Are my programs fundamentally wrong, and I'm missing the whole point or do I need to make some minor tweaks?
Thanks :)
Related
So here is the code hangs on the while loop.
client.py:
import socket
ip = "127.0.0.7"
port = 65000
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((ip, port))
while True:
file = input("Filename:")
s.sendall(file.encode())
b = b""
while True:
data = s.recv(4096)
if not data:
break
b+=data
with open(file, "wb") as f:
f.write(donne)
break
server.py:
import socket
import os
ip = "127.0.0.7"
port = 65000
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((ip, port))
s.listen(5)
conn, addr = s.accept()
while True:
receive = conn.recv(1024).decode()
if os.path.exists(receive):
with open(receive, "rb") as f:
data = f.read()
conn.sendall(data)
break
else:
print("File not found")
The problem is with the client code.
I would like to receive all the data and write them to a file but the loop in client.py does not stop.
I'm trying to send webcam captured images from pi to pc, but while using socket programming for it, i'm getting a significant amount of delay (about 5-6 seconds per image). Am I doing something wrong over here? Is there a way to reduce this delay or any other better technique to send the data to pc with minimum delay?
Server side:
import socket
port = 60000
s = socket.socket()
host = ""
s.bind((host, port))
s.listen(5)
print('Server listening....')
while True:
conn, addr = s.accept()
print 'Got connection from', addr
data = conn.recv(1024)
print('Server received', repr(data))
filename='mytext.txt'
f = open(filename,'rb')
l = f.read(1024)
while (l):
conn.send(l)
print('Sent ',repr(l))
l = f.read(1024)
f.close()
print('Done sending')
conn.send('Thank you for connecting')
conn.close()
Client:
import socket # Import socket module
import time
s = socket.socket() # Create a socket object
host = "192.1.1.1" #Ip address that the TCPServer is there
port = 60000 # Reserve a port for your service.
s.connect((host, port))
s.send("Hello server!")
with open('received_file.png', 'wb') as f:
print 'file opened'
start = time.time()
while True:
# print('receiving data...')
data = s.recv(1024)
# print('data=%s', (data))
if not data:
break
# write data to a file
f.write(data)
print(time.time() - start)
f.close()
print('Successfully get the file')
s.close()
print('connection closed')
I can send my data through CSV file. First, write my random numbers into CSV file then send it, but is it possible to send it directly?
my socket code:
import socket
host = 'localhost'
port = 8080
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(1)
while True:
print('\nListening for a client at',host , port)
conn, addr = s.accept()
print('\nConnected by', addr)
try:
print('\nReading file...\n')
while 1:
out = "test01"
print('Sending line', line)
conn.send(out)
except socket.error:
print ('Error Occured.\n\nClient disconnected.\n')
conn.close()
spark streaming code:
from pyspark import SparkContext
from pyspark.streaming import StreamingContext
sc = SparkContext("local[2]","deneme")
ssc = StreamingContext(sc, 10)
socket_stream = ssc.socketTextStream("localhost",8080)
random_integers = socket_stream.window( 30 )
digits = random_integers.flatMap(lambda line: line.split(" ")).map(lambda digit: (digit, 1))
digit_count = digits.reduceByKey(lambda x,y:x+y)
digit_count.pprint()
ssc.start()
This is because socket blocks sending the data and never moves on. The most basic solution is to send some amount of data and close the connection:
import socket
import time
host = 'localhost'
port = 50007
i = 0
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(1)
try:
while True:
conn, addr = s.accept()
try:
for j in range(10):
conn.send(bytes("{}\n".format(i), "utf-8"))
i += 1
time.sleep(1)
conn.close()
except socket.error: pass
finally:
s.close()
To get something more interesting check non-blocking mode with timeouts.
I coded chatting program with socket module.
(Python)
and I saw perfect send and get data.
But I found a problem.
This is my Server.py
import socket
import threading
HOST = '127.0.0.1'
PORT = 9999
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print(addr)
def sendmsg():
while True:
data = input()
data = data.encode("utf-8")
conn.send(data)
conn.close()
def getmsg():
while True:
data = conn.recv(1024)
if data is None:
break
else:
data = data.decode("utf-8", "ignore")
print(data)
conn.close()
threading._start_new_thread(sendmsg, ())
threading._start_new_thread(getmsg, ())
while True:
pass
Just on Client can connect with server.
I want to make multiple connection.
So I changed value of s.listen(1) to s.listen(2)
but It doesn't work.
Help me TT
This is client.py
import socket
import threading
HOST = "127.0.0.1"
PORT = 9999
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
def sendMsg():
while True:
data = input()
s.sendall(str.encode(data))
s.close()
def getMsg():
while True:
data = s.recv(1024)
data = data.decode("utf-8")
print(data)
s.close()
threading._start_new_thread(sendMsg, ())
threading._start_new_thread(getMsg, ())
while True:
pass
Thank you.
I am writing a simple TCP server in python, and am trying to input a timeout. My current code:
import socket
def connect():
HOST = '' # Symbolic name meaning the local host
PORT = 5007 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
s.settimeout(5)
conn, addr = s.accept()
print 'Connected by', addr
return conn
conn = connect()
while 1:
data = conn.recv(1024)
if not data: break
print data
conn.close()
Issue is when I try to connect I get an error at data = conn.recv(1024)
error: [Errno 10035] A non-blocking socket operation could not be completed immediately
Code works without the timeout.
You can turn on blocking:
# ...
conn.setblocking(1)
return conn
# ...
Try to set the timeout on the socket and the blocking on the connection. Like this:
import socket
def connect():
HOST = '' # Symbolic name meaning the local host
PORT = 5007 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5)
s.bind((HOST, PORT))
s.listen(1)
return s
s = connect()
while 1:
conn, addr = s.accept()
print 'Connected by', addr
conn.setblocking(1)
data = conn.recv(1024)
conn.close()
if not data: break
print data
s.close()
Ran into the same problem 30 minutes ago. Found a simple non-elegant work around...if you give the socket time to breathe by doing time.sleep(1), catching the 10035 error and doing a retry it works. I'm using 2.7.5...maybe this is a bug that got fixed. Not real sure.
Code sample...please understand this is very simplistic test code I use (only recv 1 byte at a time).So where 's' is the socket with a 10s timeout and 'numbytes' is number of bytes I need...
def getbytes(s,numbytes):
din = ''
socketerror10035count = 0
while True:
try:
r = s.recv(1).encode('hex')
din += r
if len(din)/2 == numbytes:
print 'returning',len(din)/2, 'bytes'
break
except socket.timeout as e:
din = 'socket timeout'
break
except socket.error as e:
if e[0] == 10035 and socketerror10035count < 5:
socketerror10035count = socketerror10035count +1
time.sleep(1)
else:
din = 'socket error'
break
except:
din = 'deaddead'
break
return din
For Python 3 and above, the above code which references e as a scriptable object will need to be changed to "e.errno". And, of course the print statements require parenthesis around the arguments.
Additionally, you may want to change the "except socket.error as e:" line to "except BlockingIOError as e:". However, the code works as is under Python 3.8.5 on Windows.