Пишу код на 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 <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fcntl.h>
#include <algorithm>
#include <cstdlib>
#include <set>
#include <map>
#include <stack>
#include <sys/wait.h>
#include <mysql/mysql.h>
#include <cstdlib>
#include <ctime>
#include <sstream>
#include <time.h>
#include <iostream>
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"<<endl;
char bufer[ 81 ];
int b;
int size;
FILE *in = fopen(path,"rb");
int i=0;
while(!feof(in)) {
b=fread(bufer,1,sizeof(bufer),in);
size=ftell(in);
printf("bytes send: %d, part:%d, pos: %ld \n",b,i,size);
if(b!=0)
send(sock,bufer,b,0);
i++;
}
fclose(in);
}
void get_pictures(int sock,char *name)
{
cout<<"\nget_picture"<<endl;
char buf[ 1024 ];
int b;
int size;
int j;
FILE *F2 = fopen(name,"wb");
while (1)
{
int nbytes = recv( sock, buf, sizeof(buf), 0 );
if ( nbytes == 0)
{
return;
}
if (nbytes < 0)
{
return ;
}
printf("bytes read: %d", nbytes);
fwrite(buf,1,sizeof(buf),F2);
}
fclose(F2);
}
int main()
{
new_server();
}
Чтение из сокета и запись в сокет - всегда в разных потоках.
Логика пакетов делается проще - отправляйте первыми 2 или 4 байтами размер (в байтах) контента. Дальше всё просто: читаем 2(или 4) байта в цикле (сохраняем в переменную, к примеру, _len), как только что-то прочитали - заполняем буфер кусками из сокета, пока не получили длину буфера равной _len. Всё, пакет передан. Начинаем с начала.
Читать не обязательно кусками, но нужно проверять на доступность порции в буфере сокета (на случай лагов в сети).
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
Стоит такая задача: есть переменная типа int, которую должен ввести пользовательКак поставить защиту "от дурака", т
Опять у меня идиотский вопрос (простите, но впадаю в старческий маразм, "бабушка ничего не помнит")
Привет всем участникам форума! В прошлый раз я задавал вопрос по поводу генерации пилы с использованием СИ на AVRКроме @vanyamelikov мне никто не отвечал,...