всем привет. у меня снова вопрос.
необходимо осуществлять коммуникацию с хттп сервером.
посмотрел по гуглю, нашел неплохой faq. там примеры использования. (sys/socket.h).но хотелось бы услышать совет от опытных товарищей, чтобы не наступать на общепринятые грабли. Значит имеем:
ОС: RedHat
Задача: соединяюсь, логинюсь, посылаю на сервер информацию (строка) и бинарник (файл или несколько). В ответ сервер мне что то отвечает. отсоединяюсь.Хотелось бы услышать советы по реализации. Как лучше, какие методы использовать, как готовить данные.
Заранее благодарен.
если я должен посылать как multipart/form-data POST
HTTP requests, сокеты годятся для этого? там еще какие то boundary.
>если я должен посылать как multipart/form-data POST
>HTTP requests, сокеты годятся для этого? там еще какие то boundary.
Они не то бы что годятся; без них никуда. По поводу HTTP и прочего
все написано в rfc 2616, 2608, 1945; multipart/form-data см rfc 2388.boundary -- просто текст, отделяюший parts друг от друга, т.е. часть
application протокола, на транспорте (сокетах) не сказывается никак.
ok, посмотрю.вот такой вопрос. например я подготовлю кучу буферов (я так понимаю каждая form-data будет отдельно, плюс файлы побитые по 1024). как обеспечить целостность передачи всего этого добра? когда я смогу получить ответ от сервера? не получиться ли так, что он начнет слать мне ответы асинхронно.
(заранее извиняюсь, если вопросы наивные, но у меня просто мало опыта в этой области).
>Они не то бы что годятся; без них никуда. По поводу HTTP
>и прочего
>все написано в rfc 2616, 2608, 1945; multipart/form-data см rfc 2388.
>
>boundary -- просто текст, отделяюший parts друг от друга, т.е. часть
>application протокола, на транспорте (сокетах) не сказывается никак.
>вот такой вопрос. например я подготовлю кучу буферов (я так понимаю каждая
>form-data будет отдельно, плюс файлы побитые по 1024). как обеспечить целостность
>передачи всего этого добра? когда я смогу получить ответ от сервера?
>не получиться ли так, что он начнет слать мне ответы асинхронно.За целостность передачи отвечает протокол TCP.
Только вот не понятна фраза "(я так понимаю каждая form-data будет отдельно, плюс файлы побитые по 1024)". Это как - каждый кусок в отдельном http-запросе или в одном запросе кучу кусков? И что значит файлы побитые по 1024?
Если ты делаешь несколько запросов то есть два варианта (насколько я знаю):
1) ты создаёшь отдельное соединение для каждого запроса и работаешь по схеме: соединиться -> передать запрос -> получить ответ -> разъединиться.
2) ты используешь одно соединение для всех запросов и работаешь по схеме: соединиться -> передать запрос -> получить ответ -> передать запрос -> ......... -> получить ответ -> разъединиться. При таком раскладе насколько я понимаю следует сначала полностью получить ответ на один запрос и только потом посылать другой.
здесь: http://www.ecst.csuchico.edu/~beej/guide/net/html/advanced.h...говориться о том, что даже если я сделал send() это не гарантирует, что весь буфер уйдет, поэтому они рекомендуют сделать такой метод:
#include <sys/types.h>
#include <sys/socket.h>int sendall(int s, char *buf, int *len)
{
int total = 0; // how many bytes we've sent
int bytesleft = *len; // how many we have left to send
int n;while(total < *len) {
n = send(s, buf+total, bytesleft, 0);
if (n == -1) { break; }
total += n;
bytesleft -= n;
}*len = total; // return number actually sent here
return n==-1?-1:0; // return -1 on failure, 0 on success
}и для использования:
char buf[10] = "Beej!";
int len;len = strlen(buf);
if (sendall(s, buf, &len) == -1) {
perror("sendall");
printf("We only sent %d bytes because of the error!\n", len);
}далее, данные, которые будут отсылаться могут быть довольно большими (100кб). если использование вышеприведенного метода реально, то получается, что мне не обязательно все свои данные засовывать в один буфер, а я могу насобирать односвязный список например буферов, и потом пройдясь по ним и вызвав для каждого sendall() гарантированно отправить все.
Правильный ли это подход?
>здесь: http://www.ecst.csuchico.edu/~beej/guide/net/html/advanced.h...
>
>говориться о том, что даже если я сделал send() это не гарантирует,
>что весь буфер уйдет, поэтому они рекомендуют сделать такой метод:
...
> while(total < *len) {
> n = send(s, buf+total, bytesleft, 0);
> if (n == -1) { break; }Почти правильно. Для полного счастья нужно еще посмотреть на errno, и
в некоторых случаях (например, EAGAIN) пытаться продолжать....
>далее, данные, которые будут отсылаться могут быть довольно большими >(100кб). если использование вышеприведенного метода реально, то
>получается, что мне не обязательно все свои
>данные засовывать в один буфер, а я могу насобирать односвязный список
>например буферов, и потом пройдясь по ним и вызвав для каждого
>sendall() гарантированно отправить все.
>
>Правильный ли это подход?
Да.
>ok, посмотрю.
>
>вот такой вопрос. например я подготовлю кучу буферов (я так понимаю
>каждая form-data будет отдельно, плюс файлы побитые по 1024).В сокет должно уйти примерно следующее:
POST /url/of/the/requested/resource HTTP/1.0
Content-type: multipart/form-data; boundary=уникальная_строка
Content-length: посчитаете сами
Остальные заголовки по мере необходимости--уникальная_строка
Content-type: тип_данной_части
Content-disposition: по мере необходимости
Прочие заголовки, свойственные частиданные
--уникальная_строка--
и т.д.
>как обеспечить целостность
>передачи всего этого добра? когда я смогу получить ответ от сервера?
>не получиться ли так, что он начнет слать мне ответы асинхронно.Сервер начнет отвечать не раньше, чем получит все данные и сам убедится
в их целостности (поэтому важно правильно подсчитать Content-length).Заголовков много, многие из них важные, поэтому повторюсь: обязательно
прочтите rfc. Даже если решитесь на libwww и иже с нею.>(заранее извиняюсь, если вопросы наивные, но у меня просто мало опыта в
>этой области).
>
>>Они не то бы что годятся; без них никуда. По поводу HTTP
>>и прочего
>>все написано в rfc 2616, 2608, 1945; multipart/form-data см rfc 2388.
>>
>>boundary -- просто текст, отделяюший parts друг от друга, т.е. часть
>>application протокола, на транспорте (сокетах) не сказывается никак.
Спасибо огромное.
Content-lenght это я как понимаю суммарная длина тех буферов о которых я говорил.
про libwww - вроде все довольно ясно и просто. не уверен что она мне понадобиться.