it-swarm.com.ru

ОШИБКА CURL: Ошибка записи: сброс соединения по одноранговой сети - PHP Curl

У меня странная ошибка, CURL ERROR: сбой Recv: сброс соединения по пиру

Вот как это происходит, если я не подключился к серверу и вдруг при попытке подключиться к серверу через CURL в PHP я получаю сообщение об ошибке. Когда я снова запускаю сценарий CURL, ошибка исчезает и все время работает нормально, если я оставляю удаленный сервер бездействующим в течение 30 минут или перезагружаю удаленный сервер и пытаюсь подключиться снова, я получаю ошибку снова. Таким образом, кажется, что соединение бездействует, и вдруг сервер просыпается, затем работает, а затем снова спит.

Вот так выглядит мой скрипт CURL.

$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
56
Roland

Вступление 

Удаленный сервер отправил вам пакет RST, который указывает на немедленное прекращение соединения, а не на обычное рукопожатие.

Возможные причины 

A. TCP/IP 

Это может быть проблема TCP/IP, которую вам нужно решить с вашим Хостом или обновить ОС. В большинстве случаев соединение закрывается до того, как удаленный сервер завершит загрузку контента, что приведет к Connection reset by peer..... 

B. Kannel Bug

Обратите внимание, что есть некоторые проблемы с масштабированием окна TCP в некоторых ядрах Linux после v2.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

C. 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

D. Максимальная единица передачи 

Одной из распространенных причин этой ошибки является то, что размер пакетов MTU (Maximum Transmission Unit), передаваемых по сетевому соединению, был изменен по умолчанию на 1500 байтов. Если вы настроили VPN, это, скорее всего, должно измениться во время настройки 

D. Брандмауэр: iptables 

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

  • У вас есть доступ к порту 80 на этом сервере 

Пример

 -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT`
  • Ниже следует последняя строка, а не перед любым другим ПРИНЯТЬ 

Пример

  -A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-Host-prohibited 
  • Проверьте для ВСЕХ DROP, ОТКЛОНИТЬ и убедитесь, что они не блокируют ваше соединение

  • Временно разрешить все соединения, как если бы они проходили через 

эксперимент 

Попробуйте другой сервер или удаленный сервер (так много платного облачного хостинга в сети) и протестируйте один и тот же сценарий .. если он работает, то я думаю, что это так же хорошо, как истина ... You need to update your system 

Другие, связанные с кодом 

A. SSL 

Если Yii::app()->params['pdfUrl'] является URL-адресом с https, не включающим надлежащие настройки SSL, это также может привести к этой ошибке в старой версии curl 

Решение: убедитесь, что OpenSSL установлен и включен, а затем добавьте его в свой код 

curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, false);

Я надеюсь, что это помогает 

89
Baba

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

Обычно сетевая ошибка разрешается сама по себе, если немного времени, но, похоже, вы уже дали ей немного времени.

у cURL иногда возникают проблемы с SSL и SSL-сертификатами . Я думаю, что ваш Apache и/или PHP был скомпилирован с последней версией библиотек cURL и cURL SSL, плюс я не думаю, что OpenSSL был установлен в ваш веб-сервер.

Хотя я не могу быть уверен, однако, я считаю, что cURL исторически был ненадежным с SSL-сертификатами, тогда как Open SSL этого не делает.

В любом случае, попробуйте установить Open SSL на сервер и попробуйте снова, и это должно помочь вам избавиться от этой ошибки.

10
Aamer

Так какой 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, но ... это правильно? Я вижу некоторые комментарии о том, что интернет-сети с таким числом неверны (особенно в старых версиях) ... если это число слишком мало (например), вы получите сброс соединения до того, как все данные будут отправлены. Вы можете вручную вставить заголовок:

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);
3
Rudu

Это проблема брандмауэра. Если вы используете приложение VMware, убедитесь, что брандмауэр на антивирусе выключен или разрешает подключения.

Если этот сервер находится в защищенной сети, ознакомьтесь с правилами брандмауэра сервера.

Спасибо Ганеш ПНС

1
GANESH

Я столкнулся с той же ошибкой, но по-другому.

Когда вы скручиваете страницу с определенным протоколом SSL.

curl --sslv3 https://example.com

Если --sslv3 не поддерживается целевым сервером, то ошибка будет 

curl: (35) TCP соединение сбрасывается одноранговым

С поддерживаемым протоколом ошибка исчезнет.

curl --tlsv1.2 https://example.com
0
xs2rashid

В моем случае была проблема с URL. Я использую https://example.com - но они обеспечивают "www." - поэтому, когда я переключился на https://www.example.com все было в порядке. Надлежащий заголовок был отправлен «Хост: www.example.com».

Вы можете попробовать сделать запрос в firefox brwoser, сохранить его и скопировать как cURL - так я и нашел.

0
Radek