Creating a chat program. How to make two converse simultaneously?

3
# -*- coding: utf-8 -*-
#!/usr/bin/python3
import socket
# nao tem servidor UDP no google -> vamos usar netcat como servidor UDP!
#Programa de chat: so fala um de cada vez
#implementar falando ao mesmo tempo

client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

"""
pacotes_recebidos = client.recvfrom(1024) devolve uma tupla:
(' llallalaaaa\n', ('192.168.1.4', 667))

msg recebida + (IP,porta)
"""
try:    
    while 6: #while True
        #client.sendto(input("Voce: ") + "\n", ("192.168.1.4", 668))
        #client.sendto (bytes(input("Voce: ")).encode('utf8') + bytes("\n").encode('utf8'), bytes(("192.168.1.4", 668)).encode('utf8'))
        client.sendto((input("Voce: ")).encode('utf8') + ("\n").encode('‌​utf‌​8'),("192.168.1.7", 661))
        # endereço do servidor UDP do kali linux usando netcat
        msg, friend = client.recvfrom(1024)
        print(str(friend) + ": " + str(msg))
 #se quiser apenas o ip: use friend[0]

    client.close()

except Exception as erro:
    print("Conexao falhou ")
    print("O erro foi: ", erro)
    client.close()

The above program in Python 2.7 worked by switching input by raw_input and I do not know why.

When I run Python 3.5 (with input instead of raw_input ) I tried to send a "hi" message and the following error occurred:

  

('The error was:', NameError ("name 'oi' is not defined",))

I would like to get 2 people to talk simultaneously, how to do it? At the moment, only one person at a time can type the message.

We have to wait for one of the participants to type and type Enter to continue.

This is the client. I am using netcat as the server. Could someone help me?

    
asked by anonymous 16.08.2016 / 00:07

1 answer

4
  

The above program in Python 2.7 worked by switching input by raw_input and I do not know why.

In Python 2.x method input is used to interpret and evaluate expressions , see an example:

Python 2.7.12 (default, Jul  1 2016, 15:12:24) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> input()
5 + 9
14
>>> x = input()
"stack"
>>> y = input()
"overflow"
>>> x + y
'stackoverflow'
>>>

The reported error, NameError , indicates that you are running < in in Python 2.x .

For more information see the question: input() and raw_input()

  

At the moment, only one person at a time can type the message, we have to wait for one of the participants to type and type to continue.

This happens because by default a socket is blocking, configured to send and receive information, pausing to execute script until a certain action is completed.

For example, calls to the send() method will wait for space available in buffer to send data, method calls recv() in turn, will wait until the other part of the communication sends the data to be read.

The control is not returned to the program until it has space in the buffer for sending, or some byte is received from the other part of the communication, or some error occurs .

In Python to use socket as non-blocking, the socket.setblocking with the argument False , or the socket.settimeout with the value 0 .

import socket

cliente = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
cliente.setblocking(False)

The module select will be used to monitor data entry of the user in the terminal.

  

This module provides access to the select() and poll() functions   available in most operating systems, devpoll() on Solaris   and derivatives, epoll() available on Linux 2.5+ and kqueue()   available on most BSD. Note that on Windows , it only works for    sockets ; on other operating systems, it also works for other file   types (in particular, on Unix, it works on pipes ). It can not be used   on regular files to determine whether a file has been grown since it was   last read.

Note : If you are using Windows, select may not have the expected behavior as seen in the text above.

Code:

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import socket, sys, select

cliente = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
cliente.setblocking(False)

serverAddr = ("192.168.1.4", 667)

def mensagem():
    # Verifica se foi digitado algo
    if select.select([sys.stdin,],[],[],0.0)[0]:
        # Formata a string para mandar "Cliente: <entrada>"
        entrada = "Cliente: {}".format(sys.stdin.readline())
        entrada = entrada.encode('utf-8')

        return entrada
    return False

try:
    while 1:
        try:
            msg, friend = cliente.recvfrom(1024)
            # friend[0] - IP / friend[1] - porta

            # rstrip() é para eliminar a quebra de linha
            msg = msg.decode('utf-8').rstrip()
            print("{}: {}".format(friend[0], msg))
        except:
            pass

        try:
            entrada = mensagem()
            if(entrada != False):
                cliente.sendto(entrada, serverAddr)

        except KeyboardInterrupt:
            sys.exit("\nChat encerrado!")

    cliente.close()

except Exception as erro:
    print("O erro foi: {}".format(erro))
    client.close()
    
18.08.2016 / 00:23