Клавиатура невидима, когда я касаюсь AppCompatEditText

Простое решение вашей проблемы - создать новое соединение для каждого файла. Код ниже делает это.

Sender

from __future__ import print_function
import socket

HOST = 'localhost'
PORT = 12345
BUFSIZE = 4096

def send_file(fname):
    with open(fname, 'rb') as f:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            sock.connect((HOST, PORT))
        except socket.error as err:
            print(err, HOST, PORT)
            sock.close()
            return

        while True:
            data = f.read(BUFSIZE)
            if not data:
                break
            while data:
                sent = sock.send(data)
                data = data[sent:]

    sock.close()

fnames = [
    'test0.jpg',
    'test1.jpg',
    'test2.jpg',
    'test3.jpg',
]

def main():
    for fname in fnames:
        send_file(fname)

if __name__ == '__main__':
    main()

Receiver

from __future__ import print_function
import socket

HOST = 'localhost'
PORT = 12345
BUFSIZE = 4096

class Receiver:
    ''' Buffer binary data from socket conn '''
    def __init__(self, conn):
        self.conn = conn
        self.buff = bytearray()

    def get(self, size):
        ''' Get size bytes from the buffer, reading
            from conn when necessary 
        '''
        while len(self.buff) < size:
            data = self.conn.recv(BUFSIZE)
            if not data:
                break
            self.buff.extend(data)
        # Extract the desired bytes
        result = self.buff[:size]
        # and remove them from the buffer
        del self.buff[:size]
        return bytes(result)

    def save(self, fname):
        ''' Save the remaining bytes to file fname '''
        with open(fname, 'wb') as f:
            if self.buff:
                f.write(bytes(self.buff))
            while True:
                data = self.conn.recv(BUFSIZE)
                if not data:
                    break
                f.write(data)

def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    try:
        sock.bind((HOST, PORT))
    except socket.error as err:
        print('Bind failed', err)
        return

    sock.listen(1)
    print('Socket now listening at', HOST, PORT)
    file_number = 0
    try:
        while True:
            conn, addr = sock.accept()
            print('Connected with', *addr)

            fname = 'image%d.jpg' % file_number
            with open(fname, 'wb') as f:
                while True:
                    data = conn.recv(BUFSIZE)
                    if not data:
                        break
                    f.write(data)
            conn.close()
            print(fname, 'saved\n')
            file_number += 1

    # Hit Break / Ctrl-C to exit
    except KeyboardInterrupt:
        print('\nClosing')

    sock.close()

if __name__ == '__main__':
    main()

Вам нужно нажать CtrlC или Break (в зависимости от вашей ОС), чтобы выйти получатель.


Но использование этих числовых имен файлов в приемнике не очень удовлетворительное, поэтому я решил сделать это немного сложнее. :) В следующей версии мы отправляем имя файла перед данными файла. Это немного сложно, потому что приемнику необходимо отделить имя файла от фактических данных файла. Если каждый вызов socket.recv соответствовал вызову socket.send, который был бы легким, но это не гарантировалось: полученные байты могут быть разделены по-разному от того, как они были отправлены. Приемнику необходимо буферизовать байты, чтобы он мог правильно разбить их. Подробнее см. Socket Programming HOWTO .

Чтобы получатель знал, где заканчивается имя файла, мы сначала отправляем один байт, который кодирует длину имени файла. Байт может содержать число от 0 до 255, поэтому этот код не может обрабатывать имена файлов дольше, чем это. После байта длины мы отправляем имя файла, закодированное с использованием UTF-8. И затем мы отправляем фактическое содержимое файла.

Приемник использует класс с именем Receiver для обработки буферизации. Этот класс имеет метод .get, который мы можем использовать для получения заданного количества байтов. Мы используем этот метод для получения длины имени файла и имени файла. И затем мы используем метод .save Receiver для сохранения полученного содержимого файла в новый файл.

Этот код немного беспорядочен, потому что он предназначен для работы на Python 2 и Python 3 в любой комбинации. Это было бы немного более аккуратно, если бы это было только для Python 3. Я жестко закодировал «localhost» как имя хоста, так как у меня только один компьютер, поэтому я не мог протестировать его по сети, но я уверен, что он будет корректно работать в сети.

Вот отправитель:

from __future__ import print_function
import socket
from struct import pack

HOST = 'localhost'
PORT = 12345
BUFSIZE = 4096

def send(sock, data):
    while data:
        sent = sock.send(data)
        data = data[sent:]

def send_file(fname):
    with open(fname, 'rb') as f:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            sock.connect((HOST, PORT))
        except socket.error as err:
            print(err, HOST, PORT)
            sock.close()
            return

        # Send the file name length & the filename itself in one packet          
        send(sock, pack('B', len(fname)) + fname.encode())
        while True:
            data = f.read(BUFSIZE)
            if not data:
                break
            send(sock, data)

    sock.close()

fnames = [
    'test1.gif',
    'test2.jpg',
    'test3.png',
    'test4.pdf',
]

def main():
    for fname in fnames:
        send_file(fname)

if __name__ == '__main__':
    main()

И вот приемник:

from __future__ import print_function
import socket
from struct import unpack

HOST = 'localhost'
PORT = 12345
BUFSIZE = 4096

class Receiver:
    ''' Buffer binary data from socket conn '''
    def __init__(self, conn):
        self.conn = conn
        self.buff = bytearray()

    def get(self, size):
        ''' Get size bytes from the buffer, reading
            from conn when necessary 
        '''
        while len(self.buff) < size:
            data = self.conn.recv(BUFSIZE)
            if not data:
                break
            self.buff.extend(data)
        # Extract the desired bytes
        result = self.buff[:size]
        # and remove them from the buffer
        del self.buff[:size]
        return bytes(result)

    def save(self, fname):
        ''' Save the remaining bytes to file fname '''
        with open(fname, 'wb') as f:
            if self.buff:
                f.write(bytes(self.buff))
            while True:
                data = self.conn.recv(BUFSIZE)
                if not data:
                    break
                f.write(data)

def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    try:
        sock.bind((HOST, PORT))
    except socket.error as err:
        print('Bind failed', err)
        return

    sock.listen(1)
    print('Socket now listening at', HOST, PORT)
    try:
        while True:
            conn, addr = sock.accept()
            print('Connected with', *addr)
            # Create a buffer for this connection
            receiver = Receiver(conn)
            # Get the length of the file name
            name_size = unpack('B', receiver.get(1))[0] 
            # Get the file name itself
            name = receiver.get(name_size).decode()
            print('name', name)
            # Save the file
            receiver.save(name)
            conn.close()
            print('saved\n')
    # Hit Break / Ctrl-C to exit
    except KeyboardInterrupt:
        print('\nClosing')

    sock.close()

if __name__ == '__main__':
    main()

0
задан Dorokhov Yegor 19 January 2019 в 14:06
поделиться

1 ответ

я добавляю следующую строку в конструктор:

clearFocus();

и добавляю следующий код в метод onTouch:

                requestFocus();
                InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
0
ответ дан Dorokhov Yegor 19 January 2019 в 14:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: