chat program - send doesn't work - python

I have made a chat program (in this moment only host can send messages):
server:
# server
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = 'localhost'
port = 150
server.bind((host, port))
print 'Server is open\nWaiting connections...'
server.listen(1)
while True:
client, addr = server.accept()
print 'Connected by', addr
while True:
HERE IS THE PROBLEM:when i type messages and i send they , the client see only messages with a even number. why this happen?
msg = raw_input('>>>')
if msg == 'exit':
client.send(msg)
break
else:
client.send('<Host>' + msg)
client.close()
client:
# client
import socket
import time
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = 'localhost'
port = 150
client.connect((host,port))
while True:
if client.recv(1024) == 'exit':
print '<System>Host disconnected the Server...'
print '<System>Program will shoot down in 5 seconds'
time.sleep(5)
break
else:
print client.recv(1024)
client.close()

Note that you receive the message twice in the client: First, you receive a message and check whether it's the "exit" message, then a second message is received and printed. Thus, only the even messages are printed, while the odd ones are used up in the if condition.
Try changing the client code to this:
while True:
msg = client.recv(1024)
if msg == 'exit':
print '<System>Host disconnected the Server...'
print '<System>Program will shut down in 5 seconds'
time.sleep(5)
break
else:
print msg

Related

How contious send data via socket get or sending data in every second

I make some program to send data from raspberry to pc using socket communication. so I want to make raspberry to keep sending data in every second via socket if my pc send command "RUN". and stop if my pc send command "STOP".
client.py
.
.
.
def setupSocket():
try :
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
return s,'CONNECT'
except socket.error as msg:
print(msg)
def sendReceive(s, message):
try:
s.send(str.encode(message))
reply = s.recv(1024)
reply = reply.decode('utf-8')
print(reply)
return reply
except:
return 'ERR'
if __name__=='__main__':
s = setupSocket()
while True:
data = sendReceive(s,'GET')
sleep(1)
s.close()
server.py
import socket
from random import randint,random
host = ''
port = 5560
def setupServer():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Socket created.")
try:
s.bind((socket.gethostname(), 5560))
## s.bind((host, port))
except socket.error as msg:
print(msg)
print("Socket bind comlete.")
return s
def setupConnection():
s.listen(1)
conn, address = s.accept()
print("Connected to: " + address[0] + ":" + str(address[1]))
return conn
def getDustData():
data = 'some data'
return str(data)
def GET():
data = getDustData()
reply = 'MSG'+' '+data
return reply
def dataTransfer(conn):
while True:
data = conn.recv(1024)
data = data.decode('utf-8')
dataMessage = data.split(' ', 1)
command = dataMessage[0]
print(command)
if command == 'GET':
reply = GET()
else:
reply = 'Unknown Command'
conn.sendall(str.encode(reply))
conn.close()
if __name__=='__main__':
s = setupServer()
while True:
try:
conn = setupConnection()
dataTransfer(conn)
except:
pass
so how to make server keep sending data if command=='RUN' and my client keep listen to server
I want to make raspberry to keep sending data in every second via socket if my pc send command "RUN". and stop if my pc send command "STOP".
You can set a timeout on the socket.recv() operation and upon the timeout act as if a GET command were received. For this purpose change
data = conn.recv(1024)
to
try:
data = conn.recv(1024)
except socket.timeout:
data = b'GET' # simulate GET command on timeout
and add the handling of the RUN and STOP commands:
reply = ''
if command == 'GET':
reply = GET()
elif command == 'RUN':
conn.settimeout(1) # activate timeout for recv()
elif command == 'STOP':
conn.settimeout(None) # deactivate timeout for recv()

How to implement iperf module for Bandwidth monitoring in this python chatroom?

https://iperf.fr/iperf-doc.php
https://iperf.fr/
//server.py
import socket
import select
import sys
from thread import *
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if len(sys.argv) != 3:
print "Correct usage: script, IP address, port number"
exit()
IP_address = str(sys.argv[1])
Port = int(sys.argv[2])
server.bind((IP_address, Port))
server.listen(100)
list_of_clients = []
def clientthread(conn, addr):
conn.send("Welcome to this chatroom!")
while True:
try:
message = conn.recv(2048)
if message:
print "<" + addr[0] + "> " + message
message_to_send = "<" + addr[0] + "> " + message
broadcast(message_to_send, conn)
else:
remove(conn)
except:
continue
def broadcast(message, connection):
for clients in list_of_clients:
if clients!=connection:
try:
clients.send(message)
except:
clients.close()
remove(clients)
def remove(connection):
if connection in list_of_clients:
list_of_clients.remove(connection)
while True:
conn, addr = server.accept()
list_of_clients.append(conn)
print addr[0] + " connected"
start_new_thread(clientthread,(conn,addr))
conn.close()
server.close()
The client side script will simply attempt to access the server socket created at the specified IP address and port. Once it connects, it will continuously check as to whether the input comes from the server or from the client, and accordingly redirects output. If the input is from the server, it displays the message on the terminal. If the input is from the user, it sends the message that the users enters to the server for it to be broadcasted to other users.
//client.py
import socket
import select
import sys
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if len(sys.argv) != 3:
print "Correct usage: script, IP address, port number"
exit()
IP_address = str(sys.argv[1])
Port = int(sys.argv[2])
server.connect((IP_address, Port))
while True:
sockets_list = [sys.stdin, server]
read_sockets,write_socket, error_socket = select.select(sockets_list,[],[])
for socks in read_sockets:
if socks == server:
message = socks.recv(2048)
print message
else:
message = sys.stdin.readline()
server.send(message)
sys.stdout.write("<You>")
sys.stdout.write(message)
sys.stdout.flush()
server.close()

Python sockets connecting but no data transfer

Just started learning python socket programming. I'm trying to send and receive data from a Raspberry Pi 3 using python sockets. I'm running the server program on the Raspberry Pi and the client program on my laptop running Ubuntu. Both are on the same WiFi network. The program runs and the client connects to the server, but there is no data transfer. Both the client and server do nothing. The two programs run properly if I try to run them both on the same device. Here's my code :-
Client
import socket
HOST = '172.16.31.51'
PORT = 5000
BUFSIZ = 1024
if __name__ == '__main__':
client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = input("Enter hostname [%s]: " %HOST) or HOST
port = input("Enter port [%s]: " %PORT) or PORT
sock_addr = (host, int(port))
client_sock.connect(sock_addr)
payload = 'GET TIME'
try:
while True:
client_sock.send(payload.encode('utf-8'))
data = client_sock.recv(BUFSIZ)
print(repr(data))
more = input("Want to send more data to server[y/n]:")
if more.lower() == 'y':
payload = input("Enter payload: ")
else:
break
except KeyboardInterrupt:
print("Exited by user")
client_sock.close()
Server
import socket
from time import ctime
PORT = 5000
BUFSIZ = 1024
ADDR = ('', PORT)
if __name__ == '__main__':
server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server_socket.bind(ADDR)
server_socket.listen(5)
server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, 1)
while True:
print('Server waiting for connection...')
client_sock, addr = server_socket.accept()
print('Client connected from: ', addr)
while True:
data = client_sock.recv(BUFSIZ)
if not data or data.decode('utf-8') == 'END':
break
print("Received from client: %s" % data.decode('utf-8'))
print("Sending the server time to client: %s" %ctime())
try:
client_sock.send(bytes(ctime(), 'utf-8'))
except KeyboardInterrupt:
print("Exited by user")
client_sock.close()
server_socket.close()
EDIT:
The screenshots - https://imgur.com/a/NgzsC
As soon as I hit Ctrl + C, on the client side, the server seems to send some data before it disconnects from the client. Here's a screenshot of that - https://imgur.com/a/hoLwN
Your sockets work OK, but you made some other programming mistakes. Did you ever run it?
This is the modified working code.
(Hint: you can start testing just the client when you use nc -l 5000 as a simple manual server.
Client
import socket
HOST = '127.0.0.1'
PORT = 5000
BUFSIZ = 1024
if __name__ == '__main__':
client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = str(raw_input("Enter hostname [%s]: " %HOST)) or HOST
port = str(raw_input("Enter port [%s]: " %PORT)) or PORT
sock_addr = (host, int(port))
client_sock.connect(sock_addr)
payload = 'GET TIME'
try:
while True:
client_sock.send(payload.encode('utf-8'))
data = client_sock.recv(BUFSIZ)
print(repr(data))
more = raw_input("Want to send more data to server[y/n]:")
if more.lower() == 'y':
payload = str(raw_input("Enter payload: "))
else:
break
except KeyboardInterrupt:
print("Exited by user")
client_sock.close()
Server
import socket
from time import ctime
PORT = 5004
BUFSIZ = 1024
ADDR = ('', PORT)
if __name__ == '__main__':
server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server_socket.bind(ADDR)
server_socket.listen(5)
server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, 1)
while True:
print('Server waiting for connection...')
client_sock, addr = server_socket.accept()
print('Client connected from: ', addr)
while True:
data = client_sock.recv(BUFSIZ)
if not data or data.decode('utf-8') == 'END':
break
print("Received from client: %s" % data.decode('utf-8'))
print("Sending the server time to client: %s" %ctime())
try:
client_sock.send( ctime().encode('utf-8') )
except KeyboardInterrupt:
print("Exited by user")
break;
client_sock.close()
server_socket.close()

socket is not listening for multiple request

Here is the code for server -
import socket, select,re
def getSocket( idd):
return CONNECTION_LIST[idd]
def broadcast_data (sock, message):
for socket in CONNECTION_LIST:
if socket != server_socket and socket != sock :
try :
socket.send(message)
except :
socket.close()
CONNECTION_LIST.remove(socket)
def single_client (sock , message , idd):
socket = getSocket ( idd )
if socket :
socket.send(message)
else:
print "chudap"
if __name__ == "__main__":
CONNECTION_LIST = []
RECV_BUFFER = 4096
PORT = 5000
PORTC = 2225
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", PORT))
server_socket.listen(10)
listen = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
listen.bind(("0.0.0.0" , PORTC))
#listen.listen(10)
CONNECTION_LIST.append(server_socket)
CONNECTION_LIST.append(listen)
print "Chat server started on port " + str(PORT)
idd = 1
while 1:
# Get the list sockets which are ready to be read through select
read_sockets,write_sockets,error_sockets = select.select(CONNECTION_LIST,[],[])
for sock in read_sockets:
if sock == server_socket:
sockfd, addr = server_socket.accept()
CONNECTION_LIST.append(sockfd)
#name = sockfd.recv(RECV_BUFFER)
print "connected from ip %s, id assigned is %d" % (addr[0] , idd)
broadcast_data(sockfd, "client with IP %s has entered with id = %d\n" % (addr[0] , idd))
idd += 1
elif sock == listen:
print "debugging"
data,addr = listen.recvfrom(RECV_BUFFER)
print "Received server probe request from [%s:%s]"%addr
listen.sendto("iam" , addr)#(addr[0] , 2624))
listen.close()
CONNECTION_LIST.remove(listen)
listen = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
listen.bind(("0.0.0.0" , PORTC))
CONNECTION_LIST.append(listen)
else:
try:
data = sock.recv(RECV_BUFFER)
if re.findall(r'.*/msg\d+' , data):
#print "got single client message request" + data
name = "private message from " + re.findall('([^:]+): /msg(\d+)([^"]+)' , data)[0][0] + ": "
#print name
eid = int(re.findall('([^:]+): /msg(\d+)([^"]+)' , data)[0][1])
#print eid
data = re.findall('([^:]+): /msg(\d+)([^"]+)' , data)[0][2]
#print data
data = name + data
#print "single client message sent with id = %d" %eid
single_client( sock , data , int(eid))
elif data:
broadcast_data(sock, data)
except:
broadcast_data(sock, "Client (%s, %s) is offline" % addr)
print "Client (%s, %s) is offline" % addr
sock.close()
CONNECTION_LIST.remove(sock)
continue
server_socket.close()
Here is the code for client -
import socket, select, string, sys
def prompt() :
sys.stdout.write('<You>: ')
sys.stdout.flush()
def exit(sock):
print "\n Thank you for using chat application\nBye"
sock.close()
sys.exit()
def printUsage():
print "1. By default your message will be sent to all clients sitting on the chat server"
print "2. You can send a private message to a person by starting your message as \"/msg{id}{Your message}\" for example /msg2Hi will send \"hi\" to client with id 2"
print "3. For quitting simply type \"/q\" or \"/quit\""
prompt()
PORTS = 2225
PORTC = 2624
if __name__ == "__main__":
broad = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
broad.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
broad.bind(( '0.0.0.0' , 2624) )
broad.sendto(b'whoisserver', 0, ("255.255.255.255", PORTS))
broad.settimeout(10)
print 15*"-" + "WELCOME TO CHATVILLE" + 15*"-" + "\nFinding the server"
try:
data , addr = broad.recvfrom(10)
except:
print "Can't find server ! Please ensure that server is up"
broad.close()
sys.exit()
broad.close()
if data <> "iam":
print "Can't find a valid server !"
sys.exit()
host = addr[0]
port = 5000
print addr
# host = sys.argv[1]
# port = int(sys.argv[2])
# print host,port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(2)
name = raw_input("Please Enter your name: ")
try :
s.connect((host, port))
s.send(name)
except :
print 'Unable to connect'
sys.exit()
print 'Connected to remote host. Enjoy...............................'
name = "<" + name + ">" + ": "
print " - type /h to see usage instructions any time :) - "
prompt()
while 1:
socket_list = [sys.stdin, s]
read_sockets, write_sockets, error_sockets = select.select(socket_list , [], [])
for sock in read_sockets:
if sock == s:
data = sock.recv(4096)
if not data :
print '\nDisconnected from chat server'
sys.exit()
else :
print ""
sys.stdout.write(data)
prompt()
else :
msg = sys.stdin.readline()
if str.startswith(msg, "/h") or str.startswith(msg,"/help"):
printUsage()
elif str.startswith(msg, "/quit") or str.startswith(msg,"/q"):
exit(s)
else:
msg = name + msg
s.send(msg)
prompt()
Main problem is that only one client is able to connect as soon as the first client connects are to server no other client is able to discover the server.
I tried by looking at the client's code by tcpdump and I can see the packet going at port number 2225, but the socket listen is not responding at all after the first connection.
PS - earlier I was not making instance of listen socket again and again but I tried this also and it didn't work out.
In the sever broadcast_data() does not exclude the UDP socket (listen) from the sockets to write to, and so it calls send() on that socket. This fails with exception
socket.error: [Errno 89] Destination address required
because no address is supplied (and can't be with socket.send()). The exception handler then closes the UDP socket and no further messages from new clients can be received. That's why additional clients can not connect to the server.
This is a perfect example of why it is not a good idea to use a bare except, i.e. an except statement that handles all exceptions. In this case the handler closes the UDP socket without even logging the fact. There are other instances of bare except statements in your code. I suggest that you handle specific exceptions to avoid this sort of bug. You can fix it by adding the UDP socket to the list of sockets to ignore:
def broadcast_data(sock, message):
for socket in CONNECTION_LIST:
if socket not in (server_socket, sock, listen):
try :
socket.send(message)
except socket.error as exc:
print '!!! An error occurred while writing to client. !!!'
print exc
socket.close()
CONNECTION_LIST.remove(socket)
Now no attempt will be made to send messages to the UDP listen socket, and the socket won't be closed due to error.
P.S. the code in your main loop that closes and reopens the listen socket is not necessary.

How to send a message from the server to a client using sockets

Server
import socket
import sys
HOST = ''
PORT = 9000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
try:
s.bind((HOST, PORT))
except socket.error , msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
s.listen(10)
print 'Socket now listening'
conn, addr = s.accept()
print 'Connecting from: ' + addr[0] + ':' + str(addr[1])
while 1:
message=raw_input(">")
s.sendto(message, (addr[0], addr[1]))
print(s.recv(1024))
How do I make this send a message to the client?
I can make it reply to a string the client sends to the server, but in this case I want the server to send the first message...
Can anyone help me, The solutions on google don't seem to work properly and I'm not sure what I'm doing wrong.
Since this is the 1st Google Stack Overflow result for this, I'll post a complete, working example for both a client and a server. You can start either 1st. Verified working on Ubuntu 18.04 w/ Python 3.6.9
text_send_server.py:
# text_send_server.py
import socket
import select
import time
HOST = 'localhost'
PORT = 65439
ACK_TEXT = 'text_received'
def main():
# instantiate a socket object
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('socket instantiated')
# bind the socket
sock.bind((HOST, PORT))
print('socket binded')
# start the socket listening
sock.listen()
print('socket now listening')
# accept the socket response from the client, and get the connection object
conn, addr = sock.accept() # Note: execution waits here until the client calls sock.connect()
print('socket accepted, got connection object')
myCounter = 0
while True:
message = 'message ' + str(myCounter)
print('sending: ' + message)
sendTextViaSocket(message, conn)
myCounter += 1
time.sleep(1)
# end while
# end function
def sendTextViaSocket(message, sock):
# encode the text message
encodedMessage = bytes(message, 'utf-8')
# send the data via the socket to the server
sock.sendall(encodedMessage)
# receive acknowledgment from the server
encodedAckText = sock.recv(1024)
ackText = encodedAckText.decode('utf-8')
# log if acknowledgment was successful
if ackText == ACK_TEXT:
print('server acknowledged reception of text')
else:
print('error: server has sent back ' + ackText)
# end if
# end function
if __name__ == '__main__':
main()
text_receive_client.py
# text_receive_client.py
import socket
import select
import time
HOST = 'localhost'
PORT = 65439
ACK_TEXT = 'text_received'
def main():
# instantiate a socket object
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('socket instantiated')
# connect the socket
connectionSuccessful = False
while not connectionSuccessful:
try:
sock.connect((HOST, PORT)) # Note: if execution gets here before the server starts up, this line will cause an error, hence the try-except
print('socket connected')
connectionSuccessful = True
except:
pass
# end try
# end while
socks = [sock]
while True:
readySocks, _, _ = select.select(socks, [], [], 5)
for sock in readySocks:
message = receiveTextViaSocket(sock)
print('received: ' + str(message))
# end for
# end while
# end function
def receiveTextViaSocket(sock):
# get the text via the scoket
encodedMessage = sock.recv(1024)
# if we didn't get anything, log an error and bail
if not encodedMessage:
print('error: encodedMessage was received as None')
return None
# end if
# decode the received text message
message = encodedMessage.decode('utf-8')
# now time to send the acknowledgement
# encode the acknowledgement text
encodedAckText = bytes(ACK_TEXT, 'utf-8')
# send the encoded acknowledgement text
sock.sendall(encodedAckText)
return message
# end function
if __name__ == '__main__':
main()
Use the returned socket object from 'accept' for sending and receiving data from a connected client:
while 1:
message=raw_input(">")
conn.send(message)
print conn.recv(1024)
You just have to use send
Server.py
import socket
s = socket.socket()
port = 65432
s.bind(('0.0.0.0', port))
s.listen(5)
while True:
c, addr = s.accept()
msg = b"Hello World!"
c.send(msg)
Client.py
import socket
s = socket.socket()
port = 65432
s.connect(('127.0.0.1', port))

Categories

Resources