Страницы

Поиск по вопросам

понедельник, 13 апреля 2020 г.

Java socket: зависает соединение

#java #сокет #cpp #linux

                    
Пишу код на Java, код прикреплю ниже, там же комментарии в местах, где зависает соединение.
По документации в c =in.read(buffer); должно лежать -1 при завершении передачи. Сервер
завершает передачу файла и запускает поток на чтение, но клиент упорно ждет данных.
Клиент на java.
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class foto_url {
    public static void main(String args[]) throws IOException
    {int serverPort = 5000; // здесь обязательно нужно указать порт к которому привязывается
сервер.
            String address = "54.228.232.96";
            InetAddress ipAddress = InetAddress.getByName(address); // создаем объект
который отображает вышеописанный IP-адрес
            Socket socket = new Socket(ipAddress, serverPort); // создаем сокет используя
IP-адрес и порт сервера.
            // Берем входной и выходной потоки сокета,теперь можем получать и отсылать
данные клиентом. 
         OutputStream out = socket.getOutputStream(); 
        InputStream in = socket.getInputStream();
        System.out.println("download");
        downloadFiles(in,"new11", 1024);
        System.out.println("upload");
        uploadFiles(out,"new11", 1024);
        System.out.println("download");
        downloadFiles(in,"zzx", 1024); 
        socket.close();
    }
    public static void downloadFiles(InputStream in,String strPath, int buffSize) {
        try {

            // Конвертируем потоки в другой тип, чтоб легче обрабатывать текстовые
сообщения.
            OutputStream writer = new FileOutputStream(strPath);
            byte buffer[] = new byte[buffSize];
            int c = in.read(buffer);
            while (c > 0) {
                writer.write(buffer, 0, c);
              //c= in.available(); //При таком варианте тоже зависает
               //   in.read(buffer);
                c =in.read(buffer);//В этом месте зависает.
                System.out.println("c="+c);
            }

            writer.flush();
            writer.close();

        } catch (IOException e) {
            System.out.println(e);
        }
    }

    public static void uploadFiles(OutputStream out,String strPath, int buffSize) {
        try {

            // Конвертируем потоки в другой тип, чтоб легче обрабатывать текстовые
сообщения.
            InputStream read = new FileInputStream(strPath);
            byte buffer[] = new byte[buffSize];
            int c = read.read(buffer);
            while (c>0) {
                out.write(buffer);
                c =read.read(buffer);
            }
            out.flush();
            read.close();
        } catch (IOException e) {
            System.out.println(e);
        }
    }
}

сервер на с++ под линукс.
 #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    using namespace std;
    void send_pic(int sock, char *path);
    void get_pictures(int sock,char *name);
    int  new_server()//запускает основаной порт и экстренный порт
    {
        int listener;
        struct sockaddr_in addr;
        char buf[1024];
        int bytes_read; 
        int sock;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(5000);
        addr.sin_addr.s_addr = INADDR_ANY;

        listener = socket(AF_INET, SOCK_STREAM, 0);
        if(listener < 0)
        {
            perror("socket");
            exit(1);
        }

        if(bind(listener, (struct sockaddr *)&addr, sizeof(addr)) < 0)
        {
            perror("bind");
            close( listener );
            exit(2);
        }

        listen(listener, 1);

        while(1)
        {   int sesID=-1;
            sock = accept(listener, NULL, NULL);
            if(sock < 0)
            {
                perror("accept");
                exit(3);
            }
            switch(fork())
            {
            case -1:
                perror("fork");
                break;

            case 0:
                close(listener);
                send_pic(sock,"/home/ec2-user/pic.gif");
                get_pictures(sock,"pic/ololo.gif");
                send_pic(sock,"pic/ololo.gif");
                close(sock);
                _exit(0);

            default:
                close(sock);
            }

        }
       close(listener);
    }

    void send_pic(int sock, char *path)
    {
        cout<<"\nsend_picture"<


Ответы

Ответ 1



Чтение из сокета и запись в сокет - всегда в разных потоках. Логика пакетов делается проще - отправляйте первыми 2 или 4 байтами размер (в байтах) контента. Дальше всё просто: читаем 2(или 4) байта в цикле (сохраняем в переменную, к примеру, _len), как только что-то прочитали - заполняем буфер кусками из сокета, пока не получили длину буфера равной _len. Всё, пакет передан. Начинаем с начала. Читать не обязательно кусками, но нужно проверять на доступность порции в буфере сокета (на случай лагов в сети).

Комментариев нет:

Отправить комментарий