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

Asked

Viewed 6,497 times

2

# -*- 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 when changing input for raw_input and I don’t know why.

When running in 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 'hi' is not defined",))

Would you like to make it so that two people can 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 write and type Enter to continue.

This is the client. I am using the netcat. Someone could help me?

  • 2

    has a good toturial http://www.bogotobogo.com/python/python_network_programming_tcp_server_client_chat_server_chat_client_select.php

  • @miguel, thank you

  • Can you tell me what happens with input() x raw_input() ?

  • 1

    raw_input() does not exist in python3, it is only input(), maybe that’s what

  • Running in python 2 with raw_input() works. In python 3 I switch to input() and the error I described appears!

  • I don’t know, I ran that code here and it didn’t make that mistake

  • 1

    But in python 3.5? I’m using pycharm and python 3.5 in Backbox Linux.

  • ha... I use python 3.4

  • @Miguel, I read the tutorial but could not solve. Some suggestion?

  • See: https://www.youtube.com/watch?v=PkfwX6RjRaI . I did it a few years ago and I remember it’s good.. Python2 but it should make it 3

  • @Miguel, you said you ran the script in python 3.4 and did not give the error. How did you run it? In pycharm gives error!

  • It gave but it was not the same that gave to you. Try in line this: input("Voce: ") + "\n".encode('UTF-8')...

  • client.sendto( input("Voce: ") +" n".Encode('UTF-8') ("192.168.1.4", 668)) : Syntaxerror: invalid Character in Identifier

  • I tried: client.sendto (bytes(input("You: "),'ut f-8') + bytes(" n",'ut f-8'), bytes(("192.168.1.4", 668),'utf-8')) . The error was: Unknown encoding: ut f-8

  • If I shoot utf-8: client.sendto (bytes(input("You: ")) + bytes(" n"), bytes(("192.168.1.4", 668))) ->The error was: string argument without an encoding

  • I solved the error: only the simultaneous conversation is missing: client.sendto((input("Voce: ")). Encounter('utf8') + (" n"). Encode(' utf 8'),("192.168.1.7", 661)) print(str(Friend) + ": " + str(msg))

Show 11 more comments

1 answer

4


The above program in Python 2.7 worked when changing input for raw_input and I don’t know why.

In Python 2.x the 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 error reported, NameError, indicates that you are running the script 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 write and type to continue.

This happens because by default one socket is blocking, configured to send and receive information, pausing the execution of script until a given action is completed.

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

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

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

import socket

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

The module will be used select, to monitor user data entry into the terminal.

This module provides access to the select() and poll() functions available in Most Operating systems, devpoll() available 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 cannot be used on regular files to determine whether a file has grown last read.

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

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()

Browser other questions tagged

You are not signed in. Login or sign up in order to post.