Пытаюсь реализовать код из
этой статьи. Суть статьи состоит в том, что мы при помощи xml запросов говорим роутеру открыть порт, если я все правильно понял.
1. В первом пустом GET-запросе получаем от роутера ответ под спойлером.
Тык<?xml version="1.0"?>
<root xmlns="urn:schemas-upnp-org:device-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<device>
<deviceType>urn:schemas-upnp-org:device:InternetGatewayDevice:1</deviceType>
<friendlyName>Wireless-N Broadband Router</friendlyName>
<manufacturer>Tenda</manufacturer>
<manufacturerURL>http://www.tendacn.com</manufacturerURL>
<modelDescription>Wireless-N Broadband Router</modelDescription>
<modelName>Wireless-N Router</modelName>
<modelNumber>Wireless-N Router</modelNumber>
<serialNumber>0000001</serialNumber>
<modelURL>http://www.tendacn.com</modelURL>
<UDN>uuid:afb59702-73a3-5487-6792-b438566e61b7</UDN>
<serviceList>
<service>
<serviceType>urn:schemas-upnp-org:service:Layer3Forwarding:1</serviceType>
<serviceId>urn:upnp-org:serviceId:L3Forwarding1</serviceId>
<SCPDURL>/x_layer3forwarding.xml</SCPDURL>
<controlURL>/control?Layer3Forwarding</controlURL>
<eventSubURL>/event?Layer3Forwarding</eventSubURL>
</service>
</serviceList>
<deviceList>
<device>
<deviceType>urn:schemas-upnp-org:device:WANDevice:1</deviceType>
<friendlyName>Wireless-N Broadband Router</friendlyName>
<manufacturer>Tenda</manufacturer>
<manufacturerURL>http://www.tendacn.com</manufacturerURL>
<modelDescription>Wireless-N Broadband Router</modelDescription>
<modelName>Wireless-N Router</modelName>
<modelURL>http://www.tendacn.com</modelURL>
<UDN>uuid:a1409738-e191-138b-16f3-c4d182f31616</UDN>
<serviceList>
<service>
<serviceType>urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1</serviceType>
<serviceId>urn:upnp-org:serviceId:WANCommonIFC1</serviceId>
<SCPDURL>/x_wancommoninterfaceconfig.xml</SCPDURL>
<controlURL>/control?WANCommonInterfaceConfig</controlURL>
<eventSubURL>/event?WANCommonInterfaceConfig</eventSubURL>
</service>
</serviceList>
<deviceList>
<device>
<deviceType>urn:schemas-upnp-org:device:WANConnectionDevice:1</deviceType>
<friendlyName>Wireless-N Broadband Router</friendlyName>
<manufacturer>Tenda</manufacturer>
<manufacturerURL>http://www.tendacn.com</manufacturerURL>
<modelDescription>Wireless-N Broadband Router</modelDescription>
<modelName>Wireless-N Router</modelName>
<modelURL>http://www.tendacn.com</modelURL>
<UDN>uuid:de95db7d-392a-70a4-0e74-caf2aa770a22</UDN>
<serviceList>
<service>
<serviceType>urn:schemas-upnp-org:service:WANIPConnection:1</serviceType>
<serviceId>urn:upnp-org:serviceId:WANIPConn1</serviceId>
<SCPDURL>/x_wanipconnection.xml</SCPDURL>
<controlURL>/control?WANIPConnection</controlURL>
<eventSubURL>/event?WANIPConnection</eventSubURL>
</service>
</serviceList>
</device>
</deviceList>
</device>
</deviceList>
<presentationURL>http://192.168.0.1</presentationURL>
</device>
</root>
Далее статья говорит, что нужно взять строку controlURL, рядом с которой serviceType равен urn:schemas-upnp-org:service:WANIPConnection:1. В моем случае это
<controlURL>/control?WANIPConnection</controlURL>
2. Теперь отправляем POST-запрос на
192.168.0.1:1980/control с просьбой открыть порт. Код моего запроса под спойлером.
Тыкpublic static void AddPort(string webPath, int port, string protocol, string locIP, string desc)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(webPath);
HttpWebResponse response;
string query, responseStr;
byte[] data;
request.Method = "POST";
request.Headers.Add("Cache-Control", "no-cache");
request.Headers.Add("Pragma", "no-cache");
request.Headers.Add("SOAPAction", "\"urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping\"");
request.ContentType = "text/xml; charset=\"utf-8\"";
request.UserAgent = "Microsoft-Windows/6.1 UPnP/1.0";
query = "<?xml version=\"1.0\"?>" +
"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" +
"<SOAP-ENV:Body><m:AddPortMapping xmlns:m=\"urn:schemas-upnp-org:service:WANIPConnection:1\">" +
"<NewRemoteHost xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"string\"></NewRemoteHost>" +
"<NewExternalPort xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"ui2\">" + port + "</NewExternalPort>" +
"<NewProtocol xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"string\">" + protocol + "</NewProtocol>" +
"<NewInternalPort xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"ui2\">" + port + "</NewInternalPort>" +
"<NewInternalClient xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"string\">" + locIP + "</NewInternalClient>" +
"<NewEnabled xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"boolean\">1</NewEnabled>" +
"<NewPortMappingDescription xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"string\">" + desc + "</NewPortMappingDescription>" +
"<NewLeaseDuration xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"ui4\">0</NewLeaseDuration></m:AddPortMapping>" +
"</SOAP-ENV:Body></SOAP-ENV:Envelope>";
data = Encoding.UTF8.GetBytes(query);
request.ContentLength = data.Length;
using (Stream stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
responseStr = String.Empty;
response = (HttpWebResponse)request.GetResponse();
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
responseStr = sr.ReadToEnd();
}
Console.WriteLine(responseStr);
}
Проблема в следующем: при отправке этого запроса попросту вылетает WebExcepton с текстом "The server committed a protocol violation. Section=ResponseStatusLine" на строке
response = (HttpWebResponse)request.GetResponse();
Есть преположения почему это и как исправить (и открыть-таки порт)?