AndSolomin34
AndSolomin34

Reputation: 409

client sends data to server only once

I'm new to the socket and I want to make a small program to get time from the server. Here's the code:

Server:

import socket
import time

serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = 'localhost'
port = 9999

serversocket.bind((host, port))

serversocket.listen(5)

while True:
    clientsocket, addr = serversocket.accept()

    task = clientsocket.recv(1024)

    if not task:
        break

    if task.decode() == 't':
        stime = time.strftime('%H:%M:%S', time.localtime())
        clientsocket.send(('Server time: ' + stime).encode())
    elif
        task.decode() == 'off':
        clientsocket.close()
    else:
        pass

serversocket.close()

Client:

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = 'localhost'
port = 9999

sock.connect((host, port))

while True:
    task = input('t to get time or off to disconnect')
    sock.send(task.encode())

    if task = 'off':
        break

    time = sock.recv(1024)
    print(time.decode())

sock.close()

The first time I send 't' to the server I get the time and I asked for a task again. But never get time from the server again. The client doesn't send the task to the server. But why?

P.S. Sorry if there are typos in the code. I want to show you the program logic. The code is on the laptop with broken wi-fi. So I had to type the code again on my other laptop.

Upvotes: 2

Views: 206

Answers (2)

dado
dado

Reputation: 46

You have to use, server side, the .listen() and .accept() in a coherent way. When you specify an argument inside the .listen() you are creating a queue in which different connections can be accepted (of course with .accept()) once at a time.

Therefore the .accept() has to be written before the While True, if you want to use just one permanent connection; otherwise you have to recognise that the previous socket is already closed: I ve made this using the .setblocking(False) and trying to send/receive something (if I catch an error/an empty string then I restart the procedure).

Reference: https://docs.python.org/2/library/socket.html

Upvotes: 0

mementum
mementum

Reputation: 3203

Your code with the elif part fixed

import socket
import time

serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = 'localhost'
port = 9999

serversocket.bind((host, port))

serversocket.listen(5)

while True:
    clientsocket, addr = serversocket.accept()

    task = clientsocket.recv(1024)

    if not task:
        break

    if task.decode() == 't':
        stime = time.strftime('%H:%M:%S', time.localtime())
        clientsocket.send(('Server time: ' + stime).encode())
    elif task.decode() == 'off':
        clientsocket.close()
    else:
        pass

serversocket.close()

The problem being here

while True:
    clientsocket, addr = serversocket.accept()

After having processed your 1st command, you go again to accept a connection, but your client is working with the existing connection. The server has gone.

You need a 2nd inner loop:

while True:
    task = clientsocket.recv(1024)

    if not task:
        break

    if task.decode() == 't':
        stime = time.strftime('%H:%M:%S', time.localtime())
        clientsocket.send(('Server time: ' + stime).encode())
    elif task.decode() == 'off':
        clientsocket.close()
        break
    else:
        pass

Loop from which you break out when closing the connection after getting the off command.

After breaking out you are fit again for accept

Upvotes: 1

Related Questions