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