我有一些Python代码,用于从相机捕获图像并将其发送到C#服务器。
从客户端发送消息时,我会在数据之前加上消息大小,以便我知道要从套接字服务器端提取多少数据。
在大多数情况下,它似乎运行良好,但有时-消息似乎并非以消息大小开头。
我不确定为什么会这样,但是我不知道如何处理。
Python代码:
while True:
send_message("SEND_FRAME_DATA_HERE")
def send_message(message):
message_size = len(message.encode())
print (f"Message: {message_size} - {message}")
my_socket.sendall(struct.pack(">L", message_size) + message.encode())
C#
private const int MESSAGE_CHUNK_SIZE = 4096;
private const int MESSAGE_PREFIX_SIZE = 4;
private void _receiveMessage(IAsyncResult ar)
{
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
List<byte> messageBuffer = new List<byte>();
byte[] tempBuffer = new byte[MESSAGE_CHUNK_SIZE];
try
{
handler.EndReceive(ar);
messageBuffer.AddRange(state.messageBuffer);
while (true)
{
while (messageBuffer.Count < MESSAGE_PREFIX_SIZE)
{
handler.Receive(tempBuffer, 0, MESSAGE_CHUNK_SIZE, 0);
messageBuffer.AddRange(tempBuffer);
}
int messageLength = _getMessageLength(messageBuffer);
// Occasionally the four bytes determining message length
// are read from what appears to be mid message
if (messageLength > 20)
{
Console.Write("halp");
}
messageBuffer = messageBuffer.Skip(MESSAGE_PREFIX_SIZE).ToList();
while (messageBuffer.Count < messageLength)
{
handler.Receive(tempBuffer, 0, StateObject.messageChunkSize, 0);
messageBuffer.AddRange(tempBuffer);
}
var wholeMessage = messageBuffer.Take(messageLength).ToList();
var messageString = Encoding.Default.GetString(wholeMessage.ToArray());
Console.WriteLine(messageString);
messageBuffer = messageBuffer.Skip(messageLength).ToList();
}
}
catch (SocketException ex)
{
Console.WriteLine(ex.Message);
}
}
private int _getMessageLength(List<byte> message)
{
byte[] bytes = { message[3], message[2], message[1], message[0] };
return BitConverter.ToInt32(bytes, 0);
}
消息缓冲区应如下所示:
良好运行:
在糟糕的情况下:
答案 0 :(得分:1)
问题似乎出在此代码上:
string simple = returnSimpleObject(complex);
public class SerializeData
{
public string[] EventData { get; set; }
}
private static string returnSimpleObject(string Json)
{
JObject jobject = JObject.Parse(Json);
JToken tEventData = jobject.SelectToken("EventData");
SerializeData myEvent = tEventData.ToObject<SerializeData>();
JToken tchanges = jobject.SelectToken("EventData.ChangeSet.Change.changes");
myEvent.EventData = tchanges.ToObject<string[]>();
JsonSerializer serializer = new JsonSerializer();
StringWriter strWrite = new StringWriter();
JsonWriter myWriter = new JsonTextWriter(strWrite);
serializer.Serialize(myWriter, myEvent);
return strWrite.ToString();
}
handler.Receive(tempBuffer, 0, StateObject.messageChunkSize, 0);
messageBuffer.AddRange(tempBuffer);
返回实际读入Socket.Receive()
中的字节数。您需要保存该值,然后使用它将正确的字节数复制到tempBuffer
。
messageBuffer