Страницы

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

суббота, 6 июля 2019 г.

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

Пишу код на 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<<"
send_picture"<",b,i,size); if(b!=0) send(sock,bufer,b,0); i++; } fclose(in); }
void get_pictures(int sock,char *name) { cout<<"
get_picture"< int main() { new_server(); }


Ответ

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

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

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