CURL ERROR: отказ Recv: подключение reset по peer - PHP Curl
У меня возникла эта странная ошибка, CURL ERROR: Ошибка Recv: соединение reset с помощью peer
Вот как это происходит, если я не подключался к серверу и внезапно пытаюсь подключиться к серверу через CURL в PHP, я получаю ошибку. Когда я снова запускаю CURL script, ошибка исчезает, а затем работает хорошо все время, если я оставлю на удаленном сервере около 30 минут или перезагрузите удаленный сервер и попытайтесь подключиться снова, я снова получу ошибку. Таким образом, похоже, что соединение простаивает, а затем внезапно сервер просыпается, а затем работает, а затем снова спит.
Вот как выглядит мой CURL script.
$url = Yii::app()->params['pdfUrl'];
$body = 'title='.urlencode($title).'&client_url='.Yii::app()->params['pdfClientURL'].'&client_id='.Yii::app()->params['pdfClientID'].'&content='.urlencode(htmlentities($content));
$c = curl_init ($url);
$body = array(
"client_url"=>Yii::app()->params['pdfClientURL'],
"client_id"=>Yii::app()->params['pdfClientID'],
"title"=>urlencode($title),
"content"=>urlencode($content)
);
foreach($body as $key=>$value) { $body_str .= $key.'='.$value.'&'; }
rtrim($body_str,'&');
curl_setopt ($c, CURLOPT_POST, true);
curl_setopt ($c, CURLOPT_POSTFIELDS, $body_str);
curl_setopt ($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($c, CURLOPT_CONNECTTIMEOUT , 0);
curl_setopt ($c, CURLOPT_TIMEOUT , 20);
$pdf = curl_exec ($c);
$errorCode = curl_getinfo($c, CURLINFO_HTTP_CODE);
$curlInfo = curl_getinfo($c);
$curlError = curl_error($c);
curl_close ($c);
У меня полно идей и решений, пожалуйста, помогите, я буду признателен!
Если я завершаю вывод, чтобы увидеть, что происходит с помощью
curl_setopt ($c, CURLOPT_VERBOSE, TRUE);
curl_setopt($c, CURLOPT_STDERR, $fp);
Я получаю следующее
* About to connect() to 196.41.139.168 port 80 (#0)
* Trying 196.x.x.x... * connected
* Connected to 196.x.x.x (196.x.x.x) port 80 (#0)
> POST /serve/?r=pdf/generatePdf HTTP/1.1
Host: 196.x.x.x
Accept: */*
Content-Length: 7115
Content-Type: application/x-www-form-urlencoded
Expect: 100-continue
* Recv failure: Connection reset by peer
* Closing connection #0
012 20:23:49 GMT
< Server: Apache/2.2.15 (CentOS)
< X-Powered-By: PHP/5.3.3
< Connection: close
< Transfer-Encoding: chunked
< Content-Type: text/html; charset=UTF-8
<
* Closing connection #0
Я добавил в следующий палец удалить заголовок по умолчанию и все равно не повезло:
curl_setopt ($c, CURLOPT_HTTPHEADER, array( 'Expect:' ) );
> Accept: */* Content-Length: 8414 Content-Type:
> application/x-www-form-urlencoded
>
> * Recv failure: Connection reset by peer
> * Closing connection #0 r: Apache/2.2.15 (CentOS) < X-Powered-By: PHP/5.3.3 < Connection: close < Transfer-Encoding: chunked <
> Content-Type: text/html; charset=UTF-8 <
> * Closing connection #0
Ответы
Ответ 1
Введение
Удаленный сервер отправил вам пакет RST, который указывает на немедленное удаление соединения, а не обычное рукопожатие.
Возможные причины
а. TCP/IP
Это может быть проблема TCP/IP, которую вам необходимо решить с вашего хоста или обновить вашу ОС в большинстве случаев. Соединение закрывается перед удаленным сервером до того, как он завершит загрузку содержимого в результате Connection reset by peer
.....
В. Ошибка Kannel
Обратите внимание, что есть некоторые проблемы с масштабированием окна TCP на некоторых ядрах Linux после версии 2.6.17. Дополнительную информацию см. В следующих отчетах об ошибках:
https://bugs.launchpad.net/ubuntu/+source/linux-source-2.6.17/+bug/59331
https://bugs.launchpad.net/ubuntu/+source/linux-source-2.6.20/+bug/89160
С. Ошибка PHP и CURL
Вы используете PHP/5.3.3
, у которого тоже есть серьезные ошибки... я бы посоветовал вам работать с более новой версией PHP
и CURL
https://bugs.php.net/bug.php?id=52828
https://bugs.php.net/bug.php?id=52827
https://bugs.php.net/bug.php?id=52202
https://bugs.php.net/bug.php?id=50410
Д. Максимальный блок передачи
Одной из распространенных причин этой ошибки является то, что размер MTU (Maximum Transmission Unit) пакетов, перемещающихся по вашему сетевому соединению, был изменен с 1500 байт по умолчанию.
Если вы настроили VPN
, это скорее всего должно измениться во время конфигурации
Д. Брандмауэр: iptables
Если вы не знаете свой путь вокруг этих ребят, они могут вызвать некоторые серьезные проблемы. Попробуйте и подключитесь к серверу, к которому вы подключаетесь, чтобы проверить следующие
- У вас есть доступ к порту 80 на этом сервере.
Пример
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT`
- Ниже приведена последняя строка не ранее любого другого ACCEPT
Пример
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
-
Проверьте ВСЕ DROP, REJECT и убедитесь, что они не блокируют ваше соединение.
-
Временно разрешить все соединения, если они видят, что он вращается через
Эксперимент
Попробуйте использовать другой сервер или удаленный сервер (так много платных облачных хостингов в Интернете) и протестируйте те же самые script.., если он работает, тогда я догадывается так же хорошо, как и правда... You need to update your system
Другие связанные с кодом
а. SSL
Если Yii::app()->params['pdfUrl']
является URL с https
, не считая надлежащей настройки SSL, также может вызвать эту ошибку в старой версии curl
Разрешение: убедитесь, что OpenSSL установлен и включен, а затем добавьте его в свой код
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, false);
Я надеюсь, что это поможет
Ответ 2
Обычно эта ошибка означает, что соединение было установлено с сервером, но это соединение было закрыто удаленным сервером. Это может быть связано с медленным сервером, проблемой с удаленным сервером, сетевой проблемой или (возможно) какой-то ошибкой безопасности при отправке данных на удаленный сервер, но я нахожу это маловероятным.
Обычно сетевая ошибка будет сама разрешаться с учетом некоторого времени, но похоже, что вы уже дали ей немного времени.
cURL иногда возникает с сертификатами SSL и SSL.
Я думаю, что ваш Apache и/или PHP были скомпилированы с последней версией библиотек cURL и cURL SSL, и я не думаю, что OpenSSL был установлен на вашем веб-сервере.
Хотя я не могу быть уверен, однако, я считаю, что cURL исторически ошибочно относится к сертификатам SSL, тогда как Open SSL не делает.
В любом случае попробуйте установить Open SSL на сервере и повторите попытку, и это должно помочь вам избавиться от этой ошибки.
Ответ 3
Итак, что такое URL, который дает Yii::app()->params['pdfUrl']
? Вы говорите, что это должен быть https, но журнал показывает, что он подключается к порту 80... который почти не настроен сервером для приема соединений https. cURL достаточно умен, чтобы знать, что https должен быть на порту 443..., который предположил бы, что у вашего URL-адреса есть что-то неуклюжие: https://196.41.139.168:80/serve/?r=pdf/generatePdf
Это приведет к прекращению соединения, когда Apache на другом конце не сможет обмениваться https с вами на этом порту.
Вы понимаете, что первое определение $body
заменяется, когда вы устанавливаете $body
в массив через две строки позже? {Вероятно, это просто артефакт, который вы пытаетесь решить проблему.} Вы также не кодируете значения client_url
и client_id
(первые, возможно, содержащие символы, которые нужно экранировать!) О, и вы добавляете к $body_str
без предварительной инициализации.
Из вашего подробного вывода мы видим, что cURL добавляет заголовок content-length
, но... это правильно? Я вижу, что некоторые комментарии в интервалах этого числа ошибочны (особенно со старыми версиями)... если это число было маленьким (например), вы получили бы соединение reset, прежде чем все данные будут отправлены. Вы можете вручную вставить заголовок:
curl_setopt ($c, CURLOPT_HTTPHEADER,
array("Content-Length: ". strlen($body_str)));
О, и там есть удобная функция http_build_query
, которая преобразует массив пар имя/значение в строку с кодировкой URL для вас.
Все это сворачивается в конечный код:
$post=http_build_query(array(
"client_url"=>Yii::app()->params['pdfClientURL'],
"client_id"=>Yii::app()->params['pdfClientID'],
"title"=>$title,
"content"=>$content));
//Open to URL
$c=curl_init(Yii::app()->params['pdfUrl']);
//Send post
curl_setopt ($c, CURLOPT_POST, true);
//Optional: [try with/without]
curl_setopt ($c, CURLOPT_HTTPHEADER, array("Content-Length: ".strlen($post)));
curl_setopt ($c, CURLOPT_POSTFIELDS, $post);
curl_setopt ($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($c, CURLOPT_CONNECTTIMEOUT , 0);
curl_setopt ($c, CURLOPT_TIMEOUT , 20);
//Collect result
$pdf = curl_exec ($c);
$curlInfo = curl_getinfo($c);
curl_close($c);
Ответ 4
Это проблема с брандмауэром, если вы используете приложение VMware, убедитесь, что брандмауэр на антивирусе отключен или разрешает подключения.
Если этот сервер находится в защищенной сети, ознакомьтесь с правилами брандмауэра сервера.
Спасибо
Ганеш PNS
Ответ 5
В моем случае проблема была в URL. Я использую https://example.com - но они гарантируют 'www.' - поэтому, когда я переключился на https://www.example.com, все было в порядке. Правильный заголовок был отправлен "Host: www.example.com".
Вы можете попробовать сделать запрос в firefox brwoser, сохранить его и скопировать как cURL - так, как я его нашел.