I am writing a program to send the data continuously to the Client from the Server. In here, i am using a timestamp for sample to send it to the multiple Clients who are connected. I have used multi-threading to support multiple Clients. I want the time to be sent every 10 seconds to the client. but in my code, the client stops after receiving the first data. How to make client continuously receive the data. I tried adding while loop in Client Side but it doesn't make it possible. Any suggestions please
Here's the sample Code:
Server Side:
import socket
import os
from threading import Thread
import thread
import threading
import time
import datetime
def listener(client, address):
print "Accepted connection from: ", address
with clients_lock:
clients.add(client)
try:
while True:
data = client.recv(1024)
if not data:
break
else:
print repr(data)
with clients_lock:
for c in clients:
c.sendall(data)
finally:
with clients_lock:
clients.remove(client)
client.close()
clients = set()
clients_lock = threading.Lock()
host = socket.gethostname()
port = 10016
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host,port))
s.listen(3)
th = []
while True:
print "Server is listening for connections..."
client, address = s.accept()
timestamp = datetime.datetime.now().strftime("%I:%M:%S %p")
client.send(timestamp)
time.sleep(10)
th.append(Thread(target=listener, args = (client,address)).start())
s.close()
Client Side:
import socket
import os
from threading import Thread
import socket
import time
s = socket.socket()
host = socket.gethostname()
port = 10016
s.connect((host, port))
print (s.recv(1024))
s.close()
# close the connection
My output:
01:15:10
Required Output on clients:
01:15:10
01:15:20
01:15:30
#and should go on
Server side
while True:
client, address = s.accept()
th.append(Thread(target=listener, args = (client,address)).start())
s.close()
In def listener() change while loop to continuously send data for each thread like this
while True:
data = client.recv(1024)
if data == '0':
timestamp = datetime.datetime.now().strftime("%I:%M:%S %p")
client.send(timestamp)
time.sleep(2)
at client side add this line in while loop to send some data to satisfy the if condition
s.connect((host, port))
while True:
s.send('0')
print(s.recv(1024))
#s.close()
Related
I have written a simple server and client py using UDP. The base is working, however I want that every time a user (client) joins, he would receive a chatlog of everything that has been said.
This is my code until now:
Server:
import socket
import threading
import queue
import pickle
messages = queue.Queue()
clients = []
# AF_INET used for IPv4
# SOCK_DGRAM used for UDP protocol
ip = "localhost"
port = 5555
chatlog=[]
UDPServerSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
# binding IP and port
UDPServerSocket.bind((ip, port))
def receive():
while True:
try:
message, addr = UDPServerSocket.recvfrom(1024)
messages.put((message, addr))
chatlog.append((message,addr))
except:
pass
def broadcast():
while True:
while not messages.empty():
message, addr = messages.get()
print(message.decode())
if addr not in clients:
clients.append(addr)
for client in clients:
try:
if message.decode().startswith("SIGNUP_TAG:"):
name = message.decode()[message.decode().index(":") + 1:]
UDPServerSocket.sendto(f"{name} joined!".encode(), client)
if len(chatlog)>0:
sending= pickle.dumps(chatlog)
UDPServerSocket.sendto(sending, client)
else:
pass
else:
UDPServerSocket.sendto(message, client)
except:
clients.remove(client)
t1 = threading.Thread(target=receive)
t2 = threading.Thread(target=broadcast)
t1.start()
t2.start()
And the client
import socket
import threading
import random
client= socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client.bind(("localhost", random.randint(7000, 8000))) # random port for every client
name = "Henk" #test name
def receive():
while True:
try:
message, _ = client.recvfrom(1024)
print(message.decode())
except:
pass
t= threading.Thread(target= receive)
t.start()
#this gives the server the name of the people who have entered the server
client.sendto(f"SIGNUP_TAG: {name}".encode(), ("localhost", 5555))
while True:
message= input("")
if message=="!q":
exit()
else:
client.sendto(f'[{name}]: {message}'.encode(), ("localhost",5555))
So I am actually a bit stuck on how I will approach this. Shall create a text file where every time that a message is written it gets written on the file as well? Or shall I create some kind of string list/database where every message is stored :/
I have implemented code for a server and a client using sockets, however I would like the server to send continuously and the client to receive and print the message received until I end either program. The code just prints out once "L2" on the client.
Is it ideal to reverse functionality by receiving with the server and sending with the client?
client.py
import socket
import time
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname, 1223))
while True:
msg = s.recv(5)
# clientsocket.close()
print(msg.decode("utf-8"))
server.py
import socket
import time
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 1223))
s.listen(3)
while True:
clientsocket, address = s.accept()
clientsocket.send(bytes("L2", "utf-8"))
time.sleep(2)
Python: Accept connections into a list, and have the user select a specific socket to write to?
I want to program a simple Python server that accepts incoming connections, stores them into a list, and has a user-interface that lets the user select which socket to write to.
So, while the server accepts new connections and prints received data to screen, the user should have a UI like:
> select 2 # select connection 2
> helloworld # writes 'helloworld' to the socket
How can I do this using threads or subprocesses? (what is the best approach?)
Bonus: How can I do so, that received data don't mess with the UI prompt?
This is my code using select.select():
#!/usr/bin/env python3
import os
import sys
import select
import socket
TCP_IP = '0.0.0.0'
TCP_PORT = 80
BUF_SZ = 1024
sock_list = []
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((TCP_IP,TCP_PORT))
server.listen(10)
inputs = [server]
outputs = []
while True:
read_socks, write_socks, error_socks = select.select(inputs, outputs, inputs)
for sock in read_socks:
if sock is server:
conn,addr = server.accept()
inputs.append(conn)
print('Connection %s' % conn)
else:
data = sock.recv(BUF_SZ)
print(data)
for sock in write_socks:
None
To use threading you can simply wait on socket.accept() and when you receive a new connection handle it using a new thread. A sample code can be like this:
import socket
import sys
import threading
def worker(conn, ip, port, max_buffer_size=4096):
print('accepting connection from ip={} and port={}'.
format(ip, port, conn))
data = conn.recv(max_buffer_size)
# Do something
conn.close()
def init_server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen(PARALLEL_CONNECTIONS)
return server_socket
def run():
try:
s = init_server()
print('successfully created server socket.')
except Exception as e:
print('failed to create socket because {}'.format(e))
sys.exit()
while True:
clientsocket, addr = s.accept()
ip, port = str(addr[0]), str(addr[1])
t = threading.Thread(target=worker, args=(clientsocket, ip, port,))
t.start()
I have started to make my own TCP server and client. I was able to get the server and the client to connect over my LAN network. But when I try to have another client connect to make a three way connection, it does not work. What will happen is only when the first connected client has terminated the connection between, the server and the client, can the other client connect and start the chat session. I do not understand why this happens. I have tried threading, loops, and everything else I can think of. I would appreciate any advice. I feel like there is just one small thing i am missing and I can not figure out what it is.
Here is my server:
import socket
from threading import Thread
def whatBeip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('8.8.8.8', 0))
local_ip_address = s.getsockname()[0]
print('Current Local ip: ' + str(local_ip_address))
def clietConnect():
conn, addr = s.accept()
print 'Connection address:', addr
i = True
while i == True:
data = conn.recv(BUFFER_SIZE)
if not data:
break
print('IM Recieved: ' + data)
conn.sendall(data) # echo
whatBeip()
TCP_IP = ''
TCP_PORT = 5005
BUFFER_SIZE = 1024
peopleIn = 4
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(peopleIn)
for client in range(peopleIn):
Thread(target=clietConnect()).start()
conn.close()
Here is my client
import socket
TCP_IP = '10.255.255.3'
TCP_PORT = 5005
BUFFER_SIZE = 1024
MESSAGE = "Hello, World!"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
i = True
while i == True:
s.sendall(raw_input('Type IM: '))
data = s.recv(BUFFER_SIZE)
s.close()
This is your main problem: Thread(target=clietConnect()).start() executes the function clientConnect and uses it's return value as the Thread function (which is None, so the Thread does nothing)
Also have a look at:
1) You should wait for all connections to close instead of conn.close() in the end of the server:
threads = list()
for client in range(peopleIn):
t = Thread(target=clietConnect)
t.start()
threads.append(t)
for t in threads: t.join()
and to close the connection when no data is received:
if not data:
conn.close()
return
2) You probably want to use SO_REUSEADDR [ Socket options SO_REUSEADDR and SO_REUSEPORT, how do they differ? Do they mean the same across all major operating systems? , Python: Binding Socket: "Address already in use" ]
3) And have a look at asyncio for python
So I have created a socket program for both client and server as a basic chat. I made it so the server accepts multiple clients with threading, so that is not the problem. I am having trouble sending messages to each client that is connected to the server. I am not trying to have the server send a message it created but rather have client1 sending a message to client2 by going through the server. For some reason it will only send it back to client1.
For example, client1 will say hello and the server will send the same message back to client1 but nothing to client2. I fixed this slightly by making sure the client doesn't receive its own message but client2 is still not receiving the message from the client1.
Any help will be appreciated.
I have tried multiple changes and nothing seems to work. You can look at my code for specifics on how I did things but ask if there are any questions.
Also, there is a question where someone has asked that is similar and I thought it would give me an answer but the responses stopped going through and a solution was never fully given, so please don't just refer me to that question. that is located here: Python 3: Socket server send to multiple clients with sendto() function.
Here's the code:
CLIENT:
import socket
import sys
import thread
#Create a socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#Enter username to identify self to others
name = raw_input("Enter username: ") + ": "
#Connect socket to ip and port
host = socket.gethostname()
#host = '192.168.1.10'
server_address = (host, 4441)
sock.connect(server_address)
#function waiting to receive and print a message
def receive(nothing):
while True:
data = sock.recv(1024)
if message != data:
print data
# Send messages
while True:
#arbitrary variable allowing us to have a thread
nothing = (0, 1)
message = name + raw_input("> ")
sock.sendall(message)
#thread to receive a message
thread.start_new_thread(receive, (nothing,))
SERVER:
import socket
import sys
import thread
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind the socket to the port
host = socket.gethostname()
server_address = (host, 4441)
sock.bind(server_address)
#Listen for incoming connections
sock.listen(5)
print "Waiting for connection..."
#Variable for the number of connections
numbOfConn = 0
#Name of list used for connections
addressList = []
#Function that continuosly searches for connections
def clients(connection, addressList):
while True:
message = connection.recv(1024)
print message
#connection.sendall(message)
#for loop to send message to each
for i in range(0,numbOfConn - 1):
connection.sendto(message, addressList[i])
connection.close()
while True:
#accept a connection
connection, address = sock.accept()
print 'Got connection from', address
numbOfConn += 1
addressList.append((address))
#Thread that calls the function: clients and stores them in a tuple called connection
thread.start_new_thread(clients, (connection, addressList))
sock.close()
Please help me if you can!
EDIT:
I was able to fix it to a certain extent. It is still a little buggy but I am able to send messages back and forth now. I needed to specify the connection socket as well as the address. Here's the updated code:
SERVER
import socket
import sys
import thread
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind the socket to the port
host = socket.gethostname()
server_address = (host, 4441)
sock.bind(server_address)
#Listen for incoming connections
sock.listen(5)
print "Waiting for connection..."
#Variable for the number of connections
numbOfConn = 0
#Name of list used for connections
addressList = []
connectionList = []
#Function that continuosly searches for connections
def clients(connectionList, addressList):
while True:
for j in range(0,numbOfConn):
message = connectionList[j].recv(1024)
print message
#for loop to send message to each
for i in range(0,numbOfConn):
connectionList[i].sendto(message, addressList[i])
connection.close()
while True:
#accept a connection
connection, address = sock.accept()
print 'Got connection from', address
numbOfConn += 1
addressList.append((address))
connectionList.append((connection))
#Thread that calls the function: clients and stores them in a tuple called connection
thread.start_new_thread(clients, (connectionList, addressList))
sock.close()