загрузка данных методом POST
От: Ann_vv  
Дата: 05.08.04 11:17
Оценка:
Доброго всем времени суток.

Есть такая проблема.
Из приложения (MFC) обращаюсь к сервлету методом post. Передаю сервлету данные — файл (CHttpFile).

CInternetSession is(0,1,INTERNET_OPEN_TYPE_DIRECT);
CHttpConnection* conn = NULL;
CHttpFile* pFile = NULL;
conn = is.GetHttpConnection((LPCTSTR)m_sServerName,INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_SECURE,m_nPort);
pFile=conn->OpenRequest(CHttpConnection::HTTP_VERB_POST,szHTTPPath);
bRes = pFile->SendRequest();

... в цикле передаю данные...
pFile->Write(lpBuff,dwRead);
...
pFile->EndRequest();
pFile->Close();
conn->Close();
is.Close();

Все работает. Сервлет принимает данные из входящего(request) потока байт, тоже в цикле.
Прием данных сервлетом (выход из цикла) заканчивается сразу после вызова pFile->EndRequest(). После получения данных, сервлет может обращаться в базу, выполнять какие-то операцие, в результате чего получает данные, которые нужно вернуть обратно клиенту. Пусть это будет число или строка. response.setHeader("param_name",param_value); не работает, так как уже был сделан pFile->EndRequest().
Повторный
bRes = pFile->SendRequest();
снова вызовет сервлет, но это уже будет новый вызов, а не продолжение старого. Можно, конечно, сделать типа switch и передавать сервлету какойто код, в зависимости от которого он выполняет те или иные операции. Но тогда придется разделять функции субд на несколько, что не есть хорошо.

Как организуют двусторонний диалог между сервером и клиентом с помощью сервлетов?

Заранее спасибо.
Ann
=ann=
Re: загрузка данных методом POST
От: Mishka Норвегия  
Дата: 05.08.04 11:24
Оценка: +1
Здравствуйте, Ann_vv,

Вообще-то ты должен сразу же после Write делать Read, не закрывая соединения. Сервлет должен определить, что клиент закончил посылку данных и начать передавать данные обратно.
Re[2]: загрузка данных методом POST
От: Ann_vv  
Дата: 06.08.04 02:24
Оценка:
Здравствуйте, Mishka, Вы писали:

M>Вообще-то ты должен сразу же после Write делать Read, не закрывая соединения. Сервлет должен определить, что клиент закончил посылку данных и начать передавать данные обратно.


Спасибо за подсказку! Проверю...
=ann=
Re[2]: загрузка данных методом POST
От: Ann_vv  
Дата: 10.08.04 03:45
Оценка:
Здравствуйте, Mishka, Вы писали:

M>Вообще-то ты должен сразу же после Write делать Read, не закрывая соединения. Сервлет должен определить, что клиент закончил посылку данных и начать передавать данные обратно.


Я делаю так:

pFile=conn->OpenRequest(CHttpConnection::HTTP_VERB_POST,szHTTPPath);
pFile->SendRequestEx(dwSize);
pFile->Write(lpBuff,dwSize);
dwRead = pFile->Read(lpBuff,dwCopyBufSize);
...
На последней строчке вылетает exception "Дескриптор имеет неправильное состояние для запрошенного действия".
В сервлете код тоже довольно прост.

OutputStream l_OutputStream =null;
InputStream l_InputStream = null;
l_InputStream = request.getInputStream();
try
{
byte[] buffer = new byte[1048576];
int len = 1048576;
int nread;
while ((nread= l_InputStream.read(buffer,0,len)) != -1)
{
if (nread==0) break;
System.out.println(buffer);
}
l_InputStream.close();
l_OutputStream = response.getOutputStream();
String s1 = "test string from server";
buffer = s1.getBytes();
nread = buffer.length;
l_OutputStream.write(buffer,0,nread);
}
Дело видимо в том, что запрос был методом POST на конкретное количество байт...
=ann=
Re[3]: загрузка данных методом POST
От: Cider Россия  
Дата: 10.08.04 06:23
Оценка:
Здравствуйте, Ann_vv, Вы писали:

Вот где собака порылась:
A_>l_InputStream.close();
Ты в сервлете закрываешь соединение — не надо этого делать.

Cider
Cider
Re[4]: загрузка данных методом POST
От: Ann_vv  
Дата: 10.08.04 07:20
Оценка:
Здравствуйте, Cider, Вы писали:

C>Вот где собака порылась:

A_>>l_InputStream.close();
C>Ты в сервлете закрываешь соединение — не надо этого делать.
Нет, не в этом дело. Что-то в принципе неправильно. Пробовала вызывать
pFile->Write(lpBuff,dwSize);
pFile->Flush();
но не помогает. Вылетает тот же exception при попытке читать из потока:
dwRead = pFile->Read(lpBuff,m_dwCopyBufSize);
=ann=
Re[5]: загрузка данных методом POST
От: Mishka Норвегия  
Дата: 10.08.04 09:09
Оценка:
Здравствуйте, Ann_vv,

Поищи в google "C++"+HTTP+client
Re[3]: загрузка данных методом POST
От: Mishka Норвегия  
Дата: 10.08.04 09:11
Оценка:
Здравствуйте, Ann_vv,

Да, и кстати, проблема скорее всего не в Java. Попробуй в качестве сайта указать www.microsoft.com. Клиент должен и так работать.
Re[4]: загрузка данных методом POST
От: Cider Россия  
Дата: 10.08.04 09:42
Оценка: 1 (1) +1
Здравствуйте, Cider, Вы писали:

C>Вот где собака порылась:

A_>>l_InputStream.close();
C>Ты в сервлете закрываешь соединение — не надо этого делать.

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

Cider
Cider
Re[5]: загрузка данных методом POST
От: Ann_vv  
Дата: 10.08.04 10:13
Оценка:
Здравствуйте, Cider, Вы писали:

C>Здравствуйте, Cider, Вы писали:


C>>Вот где собака порылась:

A_>>>l_InputStream.close();
C>>Ты в сервлете закрываешь соединение — не надо этого делать.

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


C>Cider


Согласна, но ошибка не только в этом.
=ann=
Re[4]: загрузка данных методом POST
От: Ann_vv  
Дата: 11.08.04 02:09
Оценка:
Здравствуйте, Mishka, Вы писали:

M>Да, и кстати, проблема скорее всего не в Java. Попробуй в качестве сайта указать www.microsoft.com. Клиент должен и так работать.


Не работает. Мне кажется, не в этом дело. Как только в сервлет передается указанное в запросе количество байт, он быстро выполняет остальные дейстия (пишет в поток, не дожидаясь, когда клиент прочитает) и заканчивает работу (без ошибок). А по идее должен ждать, пока клиент начнет читать...
=ann=
Re[5]: загрузка данных методом POST
От: Cider Россия  
Дата: 11.08.04 08:14
Оценка:
Здравствуйте, Ann_vv, Вы писали:

A_>Здравствуйте, Mishka, Вы писали:


M>>Да, и кстати, проблема скорее всего не в Java. Попробуй в качестве сайта указать www.microsoft.com. Клиент должен и так работать.


A_>Не работает. Мне кажется, не в этом дело. Как только в сервлет передается указанное в запросе количество байт, он быстро выполняет остальные дейстия (пишет в поток, не дожидаясь, когда клиент прочитает) и заканчивает работу (без ошибок). А по идее должен ждать, пока клиент начнет читать...


Так это нормальное поведение любого HTTP сервера — прочитать запрос, обработать и послать ответ. А если клиент вдруг умер, то сервер это событие обычно мало волнует. И как сервер может узнать, что клиент начал читать ? Клиент после того как послал запрос должен начать читать ответ.

Cider
Cider
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.