我在从客户端接收文件时遇到问题。有人建议我应该使用二进制序列化来发送和接收流中的消息。你能告诉我如何序列化这个想法吗?我不久前刚学会了序列化,所以我对如何将它与我的程序联系起来很困惑。
这是'应该'序列化
的客户端 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;
}
}
谢谢。
答案 0 :(得分:2)
序列化一段数据时需遵循几条规则。 将数据转换为字节很容易,但考虑如何在另一侧重建数据。假设服务器无法了解您所发送的内容。
在您的序列化程序中,您只需将几个字符串转换为byte []并将其发送出去。例如:
string x = "abcdef";
string y = "ghijk";
var bytes = Encoding.Ascii.GetBytes(x + y);
服务器收到:"abcdefghijk"
;
服务器是否可以确定并重建字符串x和y? 由于服务器不知道x和y的长度:否。
有办法解决这个问题:
使用固定长度字段。在我的例子中,x应始终为6个字符,y应始终为5个字符。然后,服务器上的解码变得像
一样简单string x = data.Substring(0,6) string y = data.Substring(6,5)
在字段之间使用分隔符。如果你熟悉cvs,&#39;,&#39;拆分字段。然而,这有它的缺点,如何处理,&#39;字符串中的某个地方?发送的数据类似于&#34; abcdef,ghijk
&#34;
在字段内容之前发送每个字段的大小。
一个简单的方法只是澄清:字符串x将被发送为&#39; 6abcdef
&#39;和y作为&#39; 5ghijk
&#39;
手工完成所有这些事情会变得非常毛茸茸,只有在真正需要的时候才能考虑。
我会诉诸现有的框架,在这个问题上做得很好:
在这种情况下,我首先创建一个类来定义发送到服务器的数据而不是一堆字符串:
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);