Итак, я вроде уже решил проблему, с которой столкнулся. Это связано с тем, использую ли я кодирование в StreamWriter моего C# клиента, но я хочу знать, как обрабатывать эти дополнительные 3 байта независимо от этого.
Это клиент, написанный на C# и Сервер написан на Go. Почему C#? Позже в облаке появятся приложения Unity. Почему Go? Я просто хотел его использовать. Кроме того, мой серверный сервер Linux и Go легко компилируются.
Проблема заключалась в том, что данные, отправляемые с моего C# клиента, имели 3 дополнительных байта, добавленных к фронту, которые конфликтовали с помощью функции Go Json.Unmarshal
, подающей его непосредственно после поступления этих данных на сервер.
Это строка в формате JSON, оставляющая клиента C#
{"channel":0, "data": {"name":"Hasty Wombat","uuid":"e91ccc23-7e80-4189-958e-9b778dce1146","type":"Drone"}}\n
Это байтовый массив до прохождения через потоковую запись, сконфигурированную с UTF8 в клиенте C#.
_sWriter = new StreamWriter(_tStream, System.Text.Encoding.UTF8, 8192);
Длина: 108
123 34 99 104 97 110 110 101 108 34 58 48 44 32 34 100 97 116 97 34 58 32 123 34 110 97 109 101 34 58 34 72 97 115 116 121 32 87 111 109 98 97 116 34 44 34 117 117 105 100 34 58 34 101 57 49 99 99 99 50 51 45 55 101 56 48 45 52 49 56 57 45 57 53 56 101 45 57 98 55 55 56 100 99 101 49 49 52 54 34 44 34 116 121 112 101 34 58 34 68 114 111 110 101 34 125 125 10
И когда он попадает на мой Go сервер, он выглядит следующим образом:
длина: 111
[239 187 191 123 34 99 104 97 110 110 101 108 34 58 48 44 32 34 100 97 116 97 34 58 32 123 34 110 97 109 101 34 58 34 72 97 115 116 121 32 87 111 109 98 97 116 34 44 34 117 117 105 100 34 58 34 50 99 57 49 48 97 99 98 45 53 101 101 102 45 52 98 56 101 45 56 52 50 54 45 54 49 102 100 100 99 99 51 101 51 55 100 34 44 34 116 121 112 101 34 58 34 68 114 111 110 101 34 125 125 10]
Из моих быстрых исследований эти 3 дополнительных байта, добавляемые спереди, имеют делать с порядком байтов относительно UTF8. Это нормально, но это мешает моей способности разбирать этот JSON байтовый массив на карту.
func handleRequest (conn net.Conn) {
for {
data, err := bufio.NewReader(conn).ReadBytes('\n');
if err != nil {
fmt.Println("Client disconnect")
conn.Close()
return
}
var mappedData map[string]interface{}
err = json.Unmarshal(data, &mappedData)
if err != nil {
fmt.Println("err:", err)
continue
}
// ...
}
}
err: invalid character 'ï' looking for beginning of value
Функция Json.Unmarshal
в Go не любит этот байтовый массив. Сначала мой обходной путь должен был просто отрезать первые 3 байта. Но это вызывает проблемы, когда я начал добавлять Go клиентов, чей вывод TCP не добавляет эти 3 байта.
Очевидный обходной путь - просто не использовать UTF8 в моем StreamWriter на клиенте C#.
// NetworkManager.cs
_tcpconn = new TCPConnection(_ipAddress, _port, OnConnectionFailure);
if (_tcpconn.SetupSocket()) {
var data = "{\"channel\":0, \"data\": {" +
"\"name\":" + "\"" + _clientName + "\"," +
"\"uuid\":" + "\"" + _uuid + "\"," +
"\"type\":" + "\"Drone\"" +
"}}" + "\n";
_tcpconn.WriteSocket(data);
// TCPConnection.cs
public bool SetupSocket () {
try {
_socket = new TcpClient(_conHost, _conPort);
_tStream = _socket.GetStream();
// _sWriter = new StreamWriter(_tStream, System.Text.Encoding.UTF8, 8192);
_sWriter = new StreamWriter(_tStream); // Fixed my problem
_sReader = new StreamReader(_tStream);
}
catch (Exception e) {
throw new Exception("Socket error:" + e.Message);
return false;
}
_socketReady = true;
return true;
}
public void WriteSocket (string theLine) {
if (!_socketReady)
return;
try {
_sWriter.Write(theLine);
_sWriter.Flush();
}
catch {
_socketReady = false;
_onConnectionFailure();
}
}
Теперь я хочу знать, есть ли в Go что-то, что правильно декодирует байтовый массив UTF8, или что-то, что правильно определяет эти дополнительные байты (или любые дополнительные байты кодирования на самом деле), и дайте мне raw JSON хочет функция Json.Unmarshal
. Я пытаюсь сделать настройку Stream Writer универсальной, но пока не уверен, понадобится ли мне что-нибудь в кодировке UTF8 или в чем преимущества.