Перейти к содержанию
    

LwIP: подождать передачи ACK сообщения после netconn_write()

Здравствуйте!

 

Есть FTP клиент на LwIP, который передает данные на FTP сервер в пассивном режиме.

так как файл большой, то передается частями, через множество netconn_write() вызовов.

 

Нужно после передачи пакета дождаться ACK от сервера, и только потом передавать дальше.

Сначала по простоте душевной добавил в код netconn_recv(), но лыжи не поехали, уже догадываюсь почему.

 

Я так понимаю, для этого мне нужно назначить callback функцию, и в ней уже смотреть что прилетело, а из основной задаче ждать какой-нить флажок (или семафор) от этой функции.

 

Вопросы:

1. мне действительно нужно добавить callback?

2. как это сделать на уровне netconn, или нужно на tcp_ спускаться и пользовать что-то типа tcp_sent() ?

 

сейчас сделано так:

в цикле до конца файла:

{

if (ERR_OK != netconn_write(xFTPDataConn, fileBuffer, fsize, NETCONN_COPY)) goto end_err;

delay (500 ms)

}

и оно работает.

Я понимаю, что delay() можно оптимизировать, но не нравится этот путь. хочу правильно сделать.

 

Надеюсь, что решение простое, но что-то я закопался не вижу его...

заранее спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Надо в колбеке смотреть что происходит с соединением и из него отдавать семафоры.

Как-то так:

callback

case NETCONN_EVT_RCVPLUS:
        {
            if (len > 0)
            {
                xSemaphoreGive(TCPRecvOK); // что-то пришло
            }
            else
            {
                connect_err = 1;
                // close
                                 ....
            }
            break;
        }
case NETCONN_EVT_SENDPLUS:
        {

            if (len > 0)
            {
                xSemaphoreGive(TCPSendOK); //успешно отправили
            }
            break;
        }

 

Main Task:

                netconn_write(conn_TCP, buf, len, NETCONN_COPY);

                if (xSemaphoreTake(TCPSendOK, 60000) == pdTRUE)
                {
                                // типа отправили
                                }
                if (xSemaphoreTake(TCPRecvOK, 60000) == pdTRUE)
                {
                                // ответ от сервера
                                        netconn_recv(conn_TCP, &buf);
                    len = netbuf_len(buf);
                    netbuf_copy(buf, &buffer.buf[0], len);
                    netbuf_delete(buf);
                                }

 

Код ФТП клиента где-то брали или сами делаете? Мне как раз тоже надо на netconn малой кровью быстро сделать особо не вникая...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Надо в колбеке смотреть что происходит с соединением и из него отдавать семафоры.

Как-то так:

callback

....

Код ФТП клиента где-то брали или сами делаете? Мне как раз тоже надо на netconn малой кровью быстро сделать особо не вникая...

Спасибо, конечно, но у меня вопрос еще предыдущего уровня сложности не решен- этот коллбэк же нужно организовать еще? а как?

 

Про FTP: сложно сказать как делалось, я уже подхватил этот проект по дороге. Насколько я вижу и знаю, частично- что врукопашную, что с Гитхаба, ну и я уже много подкрутил подобных заморочек, ориентируясь на RFC и на интернет.

После пары лет эксплуатации этот код в разных проектах и местах, и вот нашелся у одного пользователя сервер, к которому файлы приходят, но данные в файлах битые (длина корректная, некорректные данные внутри). Причем только длинные. А вставляю задержку большую- все нормально доходит.

Вот и ковыряюсь, спасибо Wireshark работает и трафик в линии показывает, и проблема стабильная.

 

Кстати, в том что я в интернете видел- никто особенно этими проверками не заморачивается, вот и у меня тоже не сделано было. И работало везде и стабильно, до вчерашнего дня.

 

Кстати2: когда запускал сниффер, потратил наверное час чтобы понять что вокруг нет ни одного простого хаба или хоть свича с функцией мироринга портов. А двухезернетовый комп не хотел дополнительно подключать только ради сниффера. И просто подключил устройство к своему компу, а комп к интернету через Wi-Fi, а в винде кликнул опцию "сделать бридж между указанными интерфейсами"- и все, вижу полную картину в Wireshark.

 

Upd: ага, по NETCONN_EVT_RCVPLUS уже много интересного находится в исходниках LwIP, например "event_callback()" в сокетах. Может и не так оно сложно-то подключить и пользовать.

например, есть оказывается функция "netconn_new_with_callback" Кажется, это оно. завтра с утра вгрызусь в. :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, конечно, но у меня вопрос еще предыдущего уровня сложности не решен- этот коллбэк же нужно организовать еще? а как?

Как-то так:

conn_TCP = netconn_new_with_callback(NETCONN_TCP, callback);

 

void callback(struct netconn *pconn, enum netconn_evt event, u16_t len)
{

    switch (event)
    {
        case NETCONN_EVT_RCVPLUS:
        {
.......

 

Если в вашем коде FTP клиента нет коммерческой тайны, то можно им как-то воспользоваться в личных целях? :)

Изменено пользователем alex2103

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...

Если в вашем коде FTP клиента нет коммерческой тайны, то можно им как-то воспользоваться в личных целях? :)

Большое спасибо! Очень надеюсь что завтра быстро разберусь с утра. в течении дня.

 

Про исходники- не могу. Но на конкретные вопросы отвечу. вот это смотрел, кое-что подсмотрел там.

Но на самом деле RFC рулит и в интернете все разжевано, но вот нормальные исходники чтоб взять и пользовать так и не попались.

Ну и конечно просто командная строка для доступа к ftp

И еще отлично мне помог ТоталКоммандер- там при соединении с FTP пишется текстовый лог, на который можно ориентироваться как на эталон.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вроде бы можно кричать "ура" и бросать в воздух чепчики, оно заработало как надо с коллбэком. :)

 

включил коллбэк.

Это только тест, но он уже показал что и как работает. Понятно, что переделаю на семафор, сейчас чисто отладка чтобы посмотреть какой евент после чего и с какими задержками выставляется.

вот лог, как файл передается на FTP. delay в миллисекундах.

 

Что интересно- величина len плавает и не всегда совпадает с тем что Wireshark показывает.

Я понимаю когда мой пакет 1500 байт внутри самой LwIP разбивается на два понятные мне 1460+40, но вот дальше непонятно что происходит. Например, переход на "80 байт+1460 байт" это что? повторы неподтвержденного?

 

мой внутренний лог:

FTPcommand: STOR test1.vms
------------FTP start send transmit file
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 17
-- NETCONN_EVT_SENDPLUS , len = 40, delay= 15
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 15
-- NETCONN_EVT_SENDPLUS , len = 40, delay= 5
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 7
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 5
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 0
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 3
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 10
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 2
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 4
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 4
-- NETCONN_EVT_SENDPLUS , len = 320, delay= 14
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 14
-- NETCONN_EVT_SENDPLUS , len = 40, delay= 7
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 7
-- NETCONN_EVT_SENDPLUS , len = 40, delay= 15
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 15
-- NETCONN_EVT_SENDPLUS , len = 40, delay= 7
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 7
-- NETCONN_EVT_SENDPLUS , len = 40, delay= 14
-- NETCONN_EVT_SENDPLUS , len = 2920, delay= 12
-- NETCONN_EVT_SENDPLUS , len = 80, delay= 10
-- NETCONN_EVT_SENDPLUS , len = 2920, delay= 18
-- NETCONN_EVT_SENDPLUS , len = 80, delay= 4
-- NETCONN_EVT_SENDPLUS , len = 2920, delay= 17
-- NETCONN_EVT_SENDPLUS , len = 80, delay= 7
-- NETCONN_EVT_SENDPLUS , len = 2920, delay= 18
-- NETCONN_EVT_SENDPLUS , len = 80, delay= 11
-- NETCONN_EVT_SENDPLUS , len = 2920, delay= 17
-- NETCONN_EVT_SENDPLUS , len = 80, delay= 13
-- NETCONN_EVT_SENDPLUS , len = 2920, delay= 19
-- NETCONN_EVT_SENDPLUS , len = 80, delay= 11
-- NETCONN_EVT_SENDPLUS , len = 2920, delay= 19
-- NETCONN_EVT_SENDPLUS , len = 80, delay= 11
-- NETCONN_EVT_SENDPLUS , len = 2920, delay= 19
-- NETCONN_EVT_SENDPLUS , len = 80, delay= 10
-- NETCONN_EVT_SENDPLUS , len = 2920, delay= 19
-- NETCONN_EVT_SENDPLUS , len = 80, delay= 10
-- NETCONN_EVT_SENDPLUS , len = 2920, delay= 18
-- NETCONN_EVT_SENDPLUS , len = 80, delay= 11
-- NETCONN_EVT_SENDPLUS , len = 2920, delay= 19
-- NETCONN_EVT_SENDPLUS , len = 80, delay= 10
-- NETCONN_EVT_SENDPLUS , len = 2920, delay= 17
-- NETCONN_EVT_SENDPLUS , len = 80, delay= 12
-- NETCONN_EVT_SENDPLUS , len = 2920, delay= 23
-- NETCONN_EVT_SENDPLUS , len = 80, delay= 8
------------FTP end send file: OK
-- NETCONN_EVT_ERROR, len = 0, delay= 9
-- NETCONN_EVT_RCVPLUS, len = 0, delay= 9
-- NETCONN_EVT_SENDPLUS , len = 0, delay= 9
------------FTP after netconn_close
-- NETCONN_EVT_RCVPLUS, len = 0, delay= 9
-- NETCONN_EVT_SENDPLUS , len = 0, delay= 9
------------FTP after netconn_delete

 

лог Wireshark для того же файла:

Request: PASV
Response: 227 Entering Passive Mode (185,182,24,55,57,236)
Request: TYPE I
21  >  49153 [ACK] Seq=1323 Ack=475 Win=29200 Len=0
49154  >  14828 [sYN] Seq=0 Win=5840 Len=0 MSS=1460
14828  >  49154 [sYN, ACK] Seq=0 Ack=1 Win=29200 Len=0 MSS=1460
49154  >  14828 [ACK] Seq=1 Ack=1 Win=5840 Len=0
Request: SIZE test1.vms
21  >  49153 [ACK] Seq=1323 Ack=491 Win=29200 Len=0
Response: 200 TYPE is now 8-bit binary
Request: STOR test1.vms
Response: 150 Accepted data connection
49153  >  21 [ACK] Seq=507 Ack=1383 Win=4458 Len=0
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=1461 Win=32120 Len=0
FTP Data: 40 bytes
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=1501 Win=32120 Len=0
14828  >  49154 [ACK] Seq=1 Ack=2961 Win=35040 Len=0
FTP Data: 40 bytes
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=3001 Win=35040 Len=0
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=4461 Win=37960 Len=0
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=5921 Win=40880 Len=0
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=7381 Win=43800 Len=0
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=8841 Win=46720 Len=0
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=10301 Win=49640 Len=0
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=11761 Win=52560 Len=0
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=13221 Win=55480 Len=0
14828  >  49154 [ACK] Seq=1 Ack=14681 Win=58400 Len=0
FTP Data: 320 bytes
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=15001 Win=61320 Len=0
14828  >  49154 [ACK] Seq=1 Ack=16461 Win=64240 Len=0
FTP Data: 40 bytes
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=16501 Win=64240 Len=0
14828  >  49154 [ACK] Seq=1 Ack=17961 Win=64240 Len=0
FTP Data: 40 bytes
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=18001 Win=64240 Len=0
14828  >  49154 [ACK] Seq=1 Ack=19461 Win=64240 Len=0
FTP Data: 40 bytes
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=19501 Win=64240 Len=0
14828  >  49154 [ACK] Seq=1 Ack=20961 Win=64240 Len=0
FTP Data: 40 bytes
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=21001 Win=64240 Len=0
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=23921 Win=64240 Len=0
FTP Data: 80 bytes
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=24001 Win=64240 Len=0
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=26921 Win=64240 Len=0
FTP Data: 80 bytes
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=27001 Win=64240 Len=0
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=29921 Win=64240 Len=0
FTP Data: 80 bytes
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=30001 Win=64240 Len=0
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=32921 Win=64240 Len=0
FTP Data: 80 bytes
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=33001 Win=64240 Len=0
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=35921 Win=64240 Len=0
FTP Data: 80 bytes
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=36001 Win=64240 Len=0
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=38921 Win=64240 Len=0
FTP Data: 80 bytes
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=39001 Win=64240 Len=0
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=41921 Win=64240 Len=0
FTP Data: 80 bytes
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=42001 Win=64240 Len=0
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=44921 Win=64240 Len=0
FTP Data: 80 bytes
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=45001 Win=64240 Len=0
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=47921 Win=64240 Len=0
FTP Data: 80 bytes
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=48001 Win=64240 Len=0
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=50921 Win=64240 Len=0
FTP Data: 80 bytes
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=51001 Win=64240 Len=0
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=53921 Win=64240 Len=0
FTP Data: 80 bytes
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=54001 Win=64240 Len=0
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=56921 Win=64240 Len=0
FTP Data: 80 bytes
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=57001 Win=64240 Len=0
FTP Data: 1460 bytes
14828  >  49154 [ACK] Seq=1 Ack=59921 Win=64240 Len=0
FTP Data: 80 bytes
14828  >  49154 [ACK] Seq=1 Ack=60001 Win=64240 Len=0
FTP Data: 240 bytes
49154  >  14828 [FIN, ACK] Seq=60241 Ack=1 Win=5840 Len=0
14828  >  49154 [ACK] Seq=1 Ack=60241 Win=64240 Len=0
14828  >  49154 [FIN, ACK] Seq=1 Ack=60242 Win=64240 Len=0
Response: 226-File successfully transferred
49154  >  14828 [ACK] Seq=60242 Ack=2 Win=5839 Len=0
49153  >  21 [ACK] Seq=507 Ack=1478 Win=5840 Len=0

сам файл лога, гораздо удобней смотреть его (нужно переименовать в *.csv для удобства): wireshark.txt

 

собственно исходник (урезанный)

#define FTP_SEND_BUFFER 1500	//good if this buffer not shorter than network package (1460 bytes)
xFTPDataConn = netconn_new_with_callback(NETCONN_TCP, ftpdata_event_callback);
netconn_set_recvtimeout(xFTPDataConn, 1000 * 5);
xFTPDataConn->pcb.tcp->keep_idle = 5000;
xFTPDataConn->pcb.tcp->keep_intvl = 1000;
xFTPDataConn->pcb.tcp->keep_cnt = 5;
xFTPDataConn->pcb.tcp->so_options |= SOF_KEEPALIVE;
if (ERR_OK != netconn_connect(xFTPDataConn, &server_addr, serverPort)) goto end_err;
if (false == FTP_send_command(FTP_CMD_STOR, fileNameToServer)) goto end_err;
if (FTP_FILE_STATUS_OK_READY_FOR_DATA != FTP_get_reply2()) goto end_err;
vTaskDelay(500);	//DEBUG

//send file
printf ("------------FTP start send transmit file\r\n");
for (;;)
{
	if (FR_OK != FTP_FREAD(&file, fileBuffer, FTP_SEND_BUFFER, &fsize)) goto end_err;
	if (fsize == 0) break;	//the end of file, it's ok
	TCPconnected = -1;
	if (ERR_OK != netconn_write(xFTPDataConn, fileBuffer, fsize, NETCONN_COPY)) goto end_err;
	{
		cntDelay=0;
		while (TCPconnected!= 1)
		{
			vTaskDelay(1);
			cntDelay++;
			if (cntDelay > 10000) goto end_err;
		}
	}
}
printf ("------------FTP end send file: OK\r\n");
FTP_FCLOSE(&file);
netconn_close(xFTPDataConn);
printf ("------------FTP after netconn_close\r\n");
netconn_delete(xFTPDataConn);
printf ("------------FTP after netconn_delete\r\n");
if (FTP_CLOSE_DATA_CON == FTP_get_reply2())
{
	return true;
}

end_err:;


ну и сам коллбэк:
/**
 * \brief  Callback registered in the netconn layer for ftp data port
 */
void ftpdata_event_callback(struct netconn *pconn, enum netconn_evt event, u16_t len)
{
switch (event)
{
	case  NETCONN_EVT_RCVPLUS:
		printf ("-- NETCONN_EVT_RCVPLUS, len = %d, delay= %d\r\n", len, cntDelay);
		break;

	case  NETCONN_EVT_RCVMINUS:
		printf ("-- NETCONN_EVT_RCVMINUS, len = %d, delay= %d\r\n", len, cntDelay);
		break;
	case  NETCONN_EVT_SENDPLUS:
		printf ("-- NETCONN_EVT_SENDPLUS , len = %d, delay= %d\r\n", len, cntDelay);
		break;
	case  NETCONN_EVT_SENDMINUS:
		printf ("-- NETCONN_EVT_SENDMINUS , len = %d, delay= %d\r\n", len, cntDelay);
		break;
	case  NETCONN_EVT_ERROR:
		printf ("-- NETCONN_EVT_ERROR, len = %d, delay= %d\r\n", len, cntDelay);
		break;
	default: break;
}
TCPconnected = 1;	//todo: to move to the needed event case after the test.
   return;
}

 

 

Хм. Склоняюсь к тому, что неплохо бы в проекте ВСЕГДА использовать коллбэк для ЛЮБЫХ, как минимум, передающих наружу линков. Кто его знает где еще подобный трэш вылезти может, а ожидание хотя бы подтверждения окончания отсылки пакета уже очень хорошо для нормального выстраивания очереди использования ресурса.

потому как ЛЮБАЯ передача может быть задержана по разным причинам, и тогда получаем эротику, плавно переходящую в запрещенные Роскомнадзором картинки.

 

Получается, что любой не требующий коллбэка линк подразумевает что контроль целостности и доставки данных делается где-то выше, но часто об этом не думают и оставляют на "ну ведь работает же" (как, например,у меня с FTP было).

 

Еще вдогонку.

 

Попробовал вернуть ситуацию к неработоспособной- удалось при переходе к netconn_new() и простой задержке 1 мс между посылками. Если использовать netconn_new_with_callback и отладочный printf() внутри, то этого уже хватало, даже без ожидания правильного евента. Причем в отладке появились события "NETCONN_EVT_SENDMINUS ". То есть несмотря на "NETCONN_EVT_SENDMINUS" передача проходила нормально (printf все-таки длинная функция).

Это, я так понимаю, внутреннее предупреждение Lwip

NETCONN_EVT_SENDMINUS

This is only used for TCP connections, and is triggered when a sufficient amount of data has been sent on the connection that the amount of free send buffer space is now under the send buffer low water mark (configured with the CYGNUM_LWIP_TCP_SNDLOWAT CDL configuration option). The amount of data sent in the most recent transaction is passed in len.

 

FTPcommand: STOR test1.vms
------------FTP start send transmit file
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 1
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 1
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 1
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 1
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 1
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 1
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 1
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 1
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 1
-- NETCONN_EVT_SENDPLUS , len = 1460, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDPLUS , len = 2920, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDPLUS , len = 2920, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDPLUS , len = 2920, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDPLUS , len = 2920, delay= 1
-- NETCONN_EVT_SENDPLUS , len = 2920, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDMINUS , len = 1500, delay= 1
-- NETCONN_EVT_SENDPLUS , len = 2920, delay= 1
-- NETCONN_EVT_SENDPLUS , len = 2920, delay= 1
------------FTP end send file: OK

 

Если отключаю отладочные сообщения и работаю без коллбэка- получаю мусор в принятом файле.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

кажется все-таки не в этом ошибка была.

Я одновременно еще несколько вещей дергал, сейчас тестировал понемногу, отключая.

 

Однозначно ловлю мусор если выключаю принудительную установку FTP в Binary Mode командой.

Хм. Причем по содержанию битого файла ну никак не могу понять, что он в ASCII передался. И сервер не говорит ничего про режим.

файл с установкой в Binary Mode

 

0 00 53 4D 56 02 00 00 00 8D 87 01 00 E8 03 00 00 03 00 00 00 71 79 2D 59 EF CC AD 1F 88 13 00 00

32 02 00 00 00 00 00 00 00 F0 00 00 00 00 00 00 40 76 69 72 74 5F 67 65 6F 5F 78 00 00 00 00 00 00

64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00

96 00 00 00 00 3C AF A5 42 00 00 00 00 00 00 00 00 76 69 72 74 5F 67 65 6F 5F 79 00 00 00 00 00 00

128 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 02 00 00 00 01 00 00 00 01 00 00 00

160 00 00 00 00 B0 A7 A5 42 00 00 00 00 00 00 00 00 76 69 72 74 5F 67 65 6F 5F 7A 00 00 00 00 00 00

192 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 00 00 00 03 00 00 00 02 00 00 00 01 00 00 00

224 00 00 00 00 04 AB AC 42 00 00 00 00 00 00 00 00 AC F5 11 3E 2F 40 BC BD DC A4 0D 3C 02 1A 01 3E

256 00 AD 18 BE CC 30 1D B8 7A 88 DC 3D 37 8E 51 BE 13 70 8C BB 3C C2 B3 3D 9E A4 83 BE 6C B5 7C BB

288 A5 1F 8A 3D A0 A7 9C BE 30 95 2B BA B7 E9 44 3D 15 4B B3 BE D0 2C 08 3C D5 5F F1 3C 37 42 C7 BE

320 30 29 B5 3C 4F 4B 3A 3C 4D 49 DA BE E3 33 FE 3C 55 E9 88 BB 2D B8 EA BE 7F 20 0F 3D 87 5B 91 BC

 

файл без установки в Binary mode он же- файл с установкой ASCII Mode

(разница с байта со смещением 250)

0 00 53 4D 56 02 00 00 00 8D 87 01 00 E8 03 00 00 03 00 00 00 71 79 2D 59 EF CC AD 1F 88 13 00 00

32 02 00 00 00 00 00 00 00 F0 00 00 00 00 00 00 40 76 69 72 74 5F 67 65 6F 5F 78 00 00 00 00 00 00

64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00

96 00 00 00 00 3C AF A5 42 00 00 00 00 00 00 00 00 76 69 72 74 5F 67 65 6F 5F 79 00 00 00 00 00 00

128 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 02 00 00 00 01 00 00 00 01 00 00 00

160 00 00 00 00 B0 A7 A5 42 00 00 00 00 00 00 00 00 76 69 72 74 5F 67 65 6F 5F 7A 00 00 00 00 00 00

192 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 00 00 00 03 00 00 00 02 00 00 00 01 00 00 00

224 00 00 00 00 04 AB AC 42 00 00 00 00 00 00 00 00 AC F5 11 3E 2F 40 BC BD DC A4 3C 02 1A 01 3E 00

256 AD 18 BE CC 30 1D B8 7A 88 DC 3D 37 8E 51 BE 13 70 8C BB 3C C2 B3 3D 9E A4 83 BE 6C B5 7C BB A5

288 1F 8A 3D A0 A7 9C BE 30 95 2B BA B7 E9 44 3D 15 4B B3 BE D0 2C 08 3C D5 5F F1 3C 37 42 C7 BE 30

320 29 B5 3C 4F 4B 3A 3C 4D 49 DA BE E3 33 FE 3C 55 E9 88 BB 2D B8 EA BE 7F 20 0F 3D 87 5B 91 BC B0

 

Но опять же, без коллбэка все равно плохо, запросто переполню все возможные буферы при передаче много-мегабайтного файла, если буду пихать без контроля и передавать, например, через GPRS.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Однозначно ловлю мусор если выключаю принудительную установку FTP в Binary Mode командой.
Не удивительно. По умолчанию включен ASCII режим. В нем ftp сервер трактует передаваемый файл как текстовый. Вот что про это сказано в RFC -

3.1.1.1. ASCII TYPE

 

This is the default type and must be accepted by all FTP

implementations. It is intended primarily for the transfer

of text files, except when both hosts would find the EBCDIC

type more convenient.

 

The sender converts the data from an internal character

representation to the standard 8-bit NVT-ASCII

representation (see the Telnet specification). The receiver

will convert the data from the standard form to his own

internal form.

 

In accordance with the NVT standard, the <CRLF> sequence

should be used where necessary to denote the end of a line

of text. (See the discussion of file structure at the end

of the Section on Data Representation and Storage.)

Отсюда следует, что если в файле есть отдельно <CR> или <LF> то сервер может с ними поступать как ему захочется

В вашем случае он отдельный <CR> (код 0D) просто удалил.

И сервер не говорит ничего про режим.
И не должен. Он включен по умолчанию

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не удивительно. По умолчанию включен ASCII режим. В нем ftp сервер трактует передаваемый файл как текстовый.

.....

И не должен. Он включен по умолчанию

Моя проблема в том, что этот (чужой) код без принудительного переключения в Binary Mode уже сколько-то лет используется и обменивается бинарными данные с разными FTP, и вот наконец-то нашелся один сервер, который таки действительно по дефолту в ASCII работает и требует принудительного переключения в Binary mode.

Понятно, если бы по дефолту все FTP в ASCII работали, то этот глюк в софте еще до меня обнаружили и исправили бы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...