Не дождался, пока админы перенесут тему. По-этому, ещё раз обнаглею и пересоздам её сам.
Имею код сервера:
const int serverPort = 5556;
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, serverPort);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server.Bind(endPoint);
server.Listen((int)SocketOptionName.MaxConnections);
Console.WriteLine($"Server started on port {serverPort}");
while (true)
{
Socket client = server.Accept();
byte[] buffer = new byte[ushort.MaxValue];
int bytesRead = client.Receive(buffer, 0, buffer.Length, SocketFlags.None);
if (bytesRead == 0)
{
Console.WriteLine($"Zero bytes received from {client.RemoteEndPoint}");
client.Close();
continue;
}
string msg = Encoding.UTF8.GetString(buffer, 0, bytesRead);
Console.WriteLine(msg);
string answer = "HTTP/1.1 200 OK\r\n\r\n";
byte[] answerBytes = Encoding.UTF8.GetBytes(answer);
client.Send(answerBytes);
client.Close();
}
Теперь на этот сервер надо отправить POST
-запрос с некоторыми заголовками и телом.
Код:
try
{
string url = "http://127.0.0.1:5556/api";
string body = "{}";
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.Method = "POST";
httpWebRequest.ContentType = "application/json";
if (!string.IsNullOrEmpty(body))
{
byte[] bodyBytes = Encoding.UTF8.GetBytes(body);
httpWebRequest.ContentLength = bodyBytes.Length;
using (Stream requestStream = httpWebRequest.GetRequestStream())
{
requestStream.Write(bodyBytes, 0, bodyBytes.Length);
}
}
HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse();
int resultErrorCode = (int)response.StatusCode;
Console.WriteLine(resultErrorCode);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
Поскольку сервер мой - заголовки, в теории, можно вообще не отправлять. Но раз уж это HTTP
-сервер - они должны быть на месте.
Проблема в том, что запрос приходит на сервер без тела. То есть, все заголовки на месте, а тела нет.
Причём, в числе заголовков появляются ещё два, которые я не отправляю. А именно:
Expect: 100-continue
Connection: keep-alive
Первый можно отключить вот так:
httpWebRequest.ServicePoint.Expect100Continue = false;
или так:
System.Net.ServicePointManager.Expect100Continue = false;
Но это не помогает. Тело всё-равно не доходит.
Хотя, если отправлять запрос на другие серверы (например: ютуб, твич) - всё нормально. Они не выдают ошибок и возвращают то что надо. Значит, им тело уходит правильно.
Если отправлять запрос через нативный сокет:
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Connect("127.0.0.1", 5556);
string t = "POST /api HTTP/1.1\r\nContent-Length: 2\r\n\r\n{}";
byte[] bytes = Encoding.UTF8.GetBytes(t);
client.Send(bytes);
То всё нормально. На моём сервере тело видно. Но есть проблема. Если писать скачивалку на нативных сокетах, то скачивать с HTTPS
будет нельзя. Будут нужны сертификаты и прочая лабуда.
А если отправлять запрос из Postman
а - всё нормально. Тело на месте.
Как я понял, проблема в этих строчках:
using (Stream requestStream = httpWebRequest.GetRequestStream())
{
requestStream.Write(bodyBytes, 0, bodyBytes.Length);
}
Здесь тело не хочет добавляться.
И ещё я заметил, что когда клиент выполнил строчку Stream requestStream = httpWebRequest.GetRequestStream()
, сервер уже начинает обрабатывать запрос. То есть, он не ждёт, пока клиент отправит ему тело. Может по-этому тела и нет
Но почему так-то?
p.s. Могу тестовый проект на гитгаб залить.