序列化手动编写的代码
Serializing a manually written code
我在从客户端接收文件时遇到问题。有人建议我应该使用二进制序列化来发送和接收流中的消息。你能告诉我应该如何连载这个吗?不久前才了解序列化,所以我很困惑如何将它与我的程序关联起来。
这是'should'被序列化的客户端
public void sendthedata()
{
if (!_timer.Enabled) // If timer is not running send data and start refresh interval
{
SendData();
_timer.Enabled = true;
}
else // Stop timer to prevent further refreshing
{
_timer.Enabled = false;
}
}
private List<int> listedProcesses = new List<int>();
private void SendData()
{
String processID = "";
String processName = "";
String processPath = "";
String processFileName = "";
String processMachinename = "";
listBox1.BeginUpdate();
try
{
piis = GetAllProcessInfos();
for (int i = 0; i < piis.Count; i++)
{
try
{
if (!listedProcesses.Contains(piis[i].Id)) //placed this on a list to avoid redundancy
{
listedProcesses.Add(piis[i].Id);
processID = piis[i].Id.ToString();
processName = piis[i].Name.ToString();
processPath = piis[i].Path.ToString();
processFileName = piis[i].FileName.ToString();
processMachinename = piis[i].Machinename.ToString();
output.Text += "\n\nSENT DATA : \n\t" + processFileName + "\n\t" + processMachinename + "\n\t" + processID + "\n\t" + processName + "\n\t" + processPath + "\n";
}
}
catch (Exception ex)
{
wait.Abort();
output.Text += "Error..... " + ex.StackTrace;
}
NetworkStream ns = tcpclnt.GetStream();
String data = "";
data = "--++" + processFileName + " " + processMachinename + " " + processID + " " + processPath;
if (ns.CanWrite)
{
byte[] bf = new ASCIIEncoding().GetBytes(data);
ns.Write(bf, 0, bf.Length);
ns.Flush();
}
}
}
finally
{
listBox1.EndUpdate();
}
}
并在服务器中反序列化
private void recieveData()
{
NetworkStream nStream = tcpClient.GetStream();
ASCIIEncoding ascii = null;
while (!stopRecieving)
{
if (nStream.CanRead)
{
byte[] buffer = new byte[1024];
nStream.Read(buffer, 0, buffer.Length);
ascii = new ASCIIEncoding();
recvDt = ascii.GetString(buffer);
/*Received message checks if it has +@@+ then the ip is disconnected*/
bool f = false;
f = recvDt.Contains("+@@+");
if (f)
{
string d = "+@@+";
recvDt = recvDt.TrimStart(d.ToCharArray());
clientDis();
stopRecieving = true;
}
//else if (recvDt.Contains("^^"))
//{
// new Transmit_File().transfer_file(file, ipselected);
//}
/* ++-- shutsdown/restrt/logoff/abort*/
else if (recvDt.Contains("++--"))
{
string d = "++--";
recvDt = recvDt.TrimStart(d.ToCharArray());
this.Invoke(new rcvData(addToOutput));
clientDis();
}
/*--++ Normal msg*/
else if (recvDt.Contains("--++"))
{
string d = "--++";
recvDt = recvDt.TrimStart(d.ToCharArray());
this.Invoke(new rcvData(addToOutput));
}
}
Thread.Sleep(1000);
}
}
public void addToOutput()
{
if (recvDt != null && recvDt != "")
{
output.Text += "\n Received Data : " + recvDt;
recvDt = null;
}
}
谢谢。
序列化一段数据时需要遵循一些规则。
将数据转换为字节很容易,但要考虑如何在另一端重构数据。假设服务器不知道您发送的内容。
在您的序列化器中,您只需将几个字符串转换为字节[] 并将其发送过来。示例:
string x = "abcdef";
string y = "ghijk";
var bytes = Encoding.Ascii.GetBytes(x + y);
服务器收到:"abcdefghijk"
;
服务器是否可以确定和重构字符串x和y?
由于服务器不知道 x 和 y 的长度:否。
有办法解决这个问题:
使用固定长度的字段。在我的示例中,x 的长度应始终为 6 个字符,而 y 的长度应始终为 5 个字符。然后在服务器上解码变得像
一样微不足道
字符串 x = data.Substring(0, 6)
字符串 y = data.Substring(6, 5)
在字段之间使用分隔符。如果您熟悉 cvs,',' 将字段分开。然而,这有它的缺点,如何处理字符串中某处的','?发送过来的数据类似于“abcdef,ghijk
”
在字段内容之前发送每个字段的大小。
一个天真的方法只是为了澄清:字符串 x 将作为 '6abcdef
' 发送,y 作为 '5ghijk
'
手工完成所有这些事情真的很麻烦,只有在真正需要时我才会考虑这样做。
我会求助于在这个问题上做得很好的现有框架:
在这种情况下,我会首先创建一个 class 来定义发送到服务器的数据,而不是一堆字符串:
class ProcessInfo{
public string ProcessID {get;set;}
public string ProcessName {get;set;}
public string ProcessPath {get;set;}
public string ProcessFileName {get;set;}
public string ProcessMachinename {get;set;}
};
使用 Json 序列化:
var procinfo = new ProcessInfo{
ProcessId = "1",
...
};
var serialised = JsonConvert.SerializeObject(procinfo);
var bytes = Encoding.Utf8.GetBytes(serialised);
ns.Write(bytes, 0, bytes.Length);
并通过以下方式在服务器上恢复它:
var procInfo = JsonConvert.DeserializeObject<ProcessInfo>(json);
我在从客户端接收文件时遇到问题。有人建议我应该使用二进制序列化来发送和接收流中的消息。你能告诉我应该如何连载这个吗?不久前才了解序列化,所以我很困惑如何将它与我的程序关联起来。
这是'should'被序列化的客户端
public void sendthedata()
{
if (!_timer.Enabled) // If timer is not running send data and start refresh interval
{
SendData();
_timer.Enabled = true;
}
else // Stop timer to prevent further refreshing
{
_timer.Enabled = false;
}
}
private List<int> listedProcesses = new List<int>();
private void SendData()
{
String processID = "";
String processName = "";
String processPath = "";
String processFileName = "";
String processMachinename = "";
listBox1.BeginUpdate();
try
{
piis = GetAllProcessInfos();
for (int i = 0; i < piis.Count; i++)
{
try
{
if (!listedProcesses.Contains(piis[i].Id)) //placed this on a list to avoid redundancy
{
listedProcesses.Add(piis[i].Id);
processID = piis[i].Id.ToString();
processName = piis[i].Name.ToString();
processPath = piis[i].Path.ToString();
processFileName = piis[i].FileName.ToString();
processMachinename = piis[i].Machinename.ToString();
output.Text += "\n\nSENT DATA : \n\t" + processFileName + "\n\t" + processMachinename + "\n\t" + processID + "\n\t" + processName + "\n\t" + processPath + "\n";
}
}
catch (Exception ex)
{
wait.Abort();
output.Text += "Error..... " + ex.StackTrace;
}
NetworkStream ns = tcpclnt.GetStream();
String data = "";
data = "--++" + processFileName + " " + processMachinename + " " + processID + " " + processPath;
if (ns.CanWrite)
{
byte[] bf = new ASCIIEncoding().GetBytes(data);
ns.Write(bf, 0, bf.Length);
ns.Flush();
}
}
}
finally
{
listBox1.EndUpdate();
}
}
并在服务器中反序列化
private void recieveData()
{
NetworkStream nStream = tcpClient.GetStream();
ASCIIEncoding ascii = null;
while (!stopRecieving)
{
if (nStream.CanRead)
{
byte[] buffer = new byte[1024];
nStream.Read(buffer, 0, buffer.Length);
ascii = new ASCIIEncoding();
recvDt = ascii.GetString(buffer);
/*Received message checks if it has +@@+ then the ip is disconnected*/
bool f = false;
f = recvDt.Contains("+@@+");
if (f)
{
string d = "+@@+";
recvDt = recvDt.TrimStart(d.ToCharArray());
clientDis();
stopRecieving = true;
}
//else if (recvDt.Contains("^^"))
//{
// new Transmit_File().transfer_file(file, ipselected);
//}
/* ++-- shutsdown/restrt/logoff/abort*/
else if (recvDt.Contains("++--"))
{
string d = "++--";
recvDt = recvDt.TrimStart(d.ToCharArray());
this.Invoke(new rcvData(addToOutput));
clientDis();
}
/*--++ Normal msg*/
else if (recvDt.Contains("--++"))
{
string d = "--++";
recvDt = recvDt.TrimStart(d.ToCharArray());
this.Invoke(new rcvData(addToOutput));
}
}
Thread.Sleep(1000);
}
}
public void addToOutput()
{
if (recvDt != null && recvDt != "")
{
output.Text += "\n Received Data : " + recvDt;
recvDt = null;
}
}
谢谢。
序列化一段数据时需要遵循一些规则。 将数据转换为字节很容易,但要考虑如何在另一端重构数据。假设服务器不知道您发送的内容。
在您的序列化器中,您只需将几个字符串转换为字节[] 并将其发送过来。示例:
string x = "abcdef";
string y = "ghijk";
var bytes = Encoding.Ascii.GetBytes(x + y);
服务器收到:"abcdefghijk"
;
服务器是否可以确定和重构字符串x和y? 由于服务器不知道 x 和 y 的长度:否。
有办法解决这个问题:
使用固定长度的字段。在我的示例中,x 的长度应始终为 6 个字符,而 y 的长度应始终为 5 个字符。然后在服务器上解码变得像
一样微不足道字符串 x = data.Substring(0, 6) 字符串 y = data.Substring(6, 5)
在字段之间使用分隔符。如果您熟悉 cvs,',' 将字段分开。然而,这有它的缺点,如何处理字符串中某处的','?发送过来的数据类似于“
abcdef,ghijk
”在字段内容之前发送每个字段的大小。 一个天真的方法只是为了澄清:字符串 x 将作为 '
6abcdef
' 发送,y 作为 '5ghijk
'
手工完成所有这些事情真的很麻烦,只有在真正需要时我才会考虑这样做。
我会求助于在这个问题上做得很好的现有框架:
在这种情况下,我会首先创建一个 class 来定义发送到服务器的数据,而不是一堆字符串:
class ProcessInfo{
public string ProcessID {get;set;}
public string ProcessName {get;set;}
public string ProcessPath {get;set;}
public string ProcessFileName {get;set;}
public string ProcessMachinename {get;set;}
};
使用 Json 序列化:
var procinfo = new ProcessInfo{
ProcessId = "1",
...
};
var serialised = JsonConvert.SerializeObject(procinfo);
var bytes = Encoding.Utf8.GetBytes(serialised);
ns.Write(bytes, 0, bytes.Length);
并通过以下方式在服务器上恢复它:
var procInfo = JsonConvert.DeserializeObject<ProcessInfo>(json);