我正在尝试构建一个超级简单的JSON-RPC服务器,但是我在接收POST消息的主体时遇到了问题。我可以很好地接收GET消息,因为参数只包含在Host Header中。但我无法接收POST或PUT的主体。我使用了两个不同版本的Postman和cUrl来验证我实际上是在发送正确的POST消息。
我的代码相当简单;我创建一个套接字,绑定它,然后监听并保存已收到的内容。 (P是对程序类的引用)
p.sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
p.sock.Bind(new IPEndPoint(IPAddress.Any, p.config.server_port));
p.sock.Listen(5);
p.serverThread = new Thread(new ThreadStart(() => serverListen(p)));
p.serverThread.Start();
然后我使用以下块来实际接收消息:
Socket recieved = p.sock.Accept();
//handle recieved info
string message = "";
byte[] buffer = new byte[10000];
int readResult = recieved.Receive(buffer);
if (readResult > 0) {
message = Encoding.UTF8.GetString(buffer,0, readResult);
message = message;//for debugging purposes
message = ReceivedMessage.decodeURL(message);//Get rid of URL encoding
}
这适用于GET消息,但无法返回POST消息的正文。上面的代码检索以下HTTP消息:
POST / HTTP/1.1
cache-control: no-cache
Postman-Token: 5dab0e8e-910f-4c5d-a7dd-49bf5348a8d0
Content-Type: text/plain
User-Agent: PostmanRuntime/3.0.5
Accept: */*
Host: localhost:1215
accept-encoding: gzip, deflate
content-length: 18
Connection: keep-alive
根本不包含任何身体元素。我错过了什么?任何帮助将不胜感激。
答案 0 :(得分:0)
所以错误是首先发送HTTP标头,然后发送主体。或者至少我认为这是正在发生的事情。因此,为了读取正文,您必须再次调用Socket.Recieve()(或Async版本)来获取正文。这看起来像这样:
//get the rest of the body
string httpBody = string.Empty;
byte[] bodyBuffer = new byte[10000]; //arbitrary buffer length
string[] lines = message.Split('\n'); //split the header Message by newlines
string StrLength = string.Empty;
int contentLength = 0;
foreach (string line in lines) {
if (line.Contains("content-length")) {
string[] splitLine = line.Split(':');
StrLength = splitLine[1];
break;
}
}
if (StrLength != null) {
try {
contentLength = int.Parse(StrLength);
}
catch {
Console.WriteLine("Failed to parse content-length");
}
}
else {
Console.WriteLine("content-length header not found");
}
int bodyReadResult = sock.Receive(bodyBuffer);
if (bodyReadResult != contentLength) {
Console.WriteLine("Failed to read all of HTTP body, probably sent as a multipart");
}
httpBody = Encoding.ASCII.GetString(bodyBuffer, 0, bodyReadResult);