我正在尝试使用命名管道从服务器向客户端发送4个参数 - 一个整数,一个bool和两个字符串。 我尝试了不同的方法,但仍未成功。 第一种方式 - 我只是将所有参数转换为字符串并尝试发送,但在客户端我收到所有参数为null:
服务器代码:
static void StartServer()
{
var server = new NamedPipeServerStream("PipesEnroll", PipeDirection.InOut);
while (true)
{
server.WaitForConnection();
StreamWriter writer = new StreamWriter(server);
string terminalTemplate;
string matcherTemplate;
int mathVersionNumber = 9;
int numberFingers;
bool isOk = Enroll.EnrollWithoutWCF(retrievedList, mathVersionNumber, out terminalTemplate, out matcherTemplate, out numberFingers);
writer.WriteLine(isOk.ToString());
writer.WriteLine(terminalTemplate);
writer.WriteLine(matcherTemplate);
writer.WriteLine(numberFingers.ToString());
writer.Flush();
server.Disconnect();
}
客户代码:
using (var client = new NamedPipeClientStream(".", "PipesEnroll", PipeDirection.InOut))
{
client.Connect();
StreamReader reader = new StreamReader(client);
bool isOK = Convert.ToBoolean(reader.ReadLine());
string terminalTemplate = reader.ReadLine();
string matcherTemplate = reader.ReadLine();
int numberFingers = Convert.ToInt32(reader.ReadLine());
}
我做的第二种方法是创建字符串列表并在服务器上对其进行序列化,在客户端使用BinaryFormatter进行反序列化,但是遇到了这个异常:“System.Runtime.Serialization.SerializationException:在解析完成之前遇到Stream的结束”
服务器代码:
var server = new NamedPipeServerStream("PipesEnroll", PipeDirection.InOut);
while (true)
{
server.WaitForConnection();
StreamWriter writer = new StreamWriter(server);
List<string> sendList = new List<string>();
sendList.Add(isOk.ToString());
sendList.Add(terminalTemplate);
sendList.Add(matcherTemplate);
sendList.Add(numberFingers.ToString());
BinaryFormatter formatterSerialize = new BinaryFormatter();
formatterSerialize.Serialize(writer.BaseStream, sendList);
writer.Flush();
server.Disconnect();
}
客户代码:
using (var client = new NamedPipeClientStream(".", "PipesEnroll", PipeDirection.InOut))
{
client.Connect();
StreamReader reader = new StreamReader(client);
BinaryFormatter formatterDeserialize = new BinaryFormatter();
List<string> retrievedList = (List<string>) formatterDeserialize.Deserialize(reader.BaseStream);
}
答案 0 :(得分:3)
最后,我已经能够使用xml序列化和特定数据协议来执行此操作,以便读取和写入字符串。
具有我们需要从服务器传递到客户端的乘法数据的类,实现了两个用于序列化/反序列化到xml中的方法:
[Serializable]
public class ServerData
{
public bool Result { get; set; }
public int Int1 { get; set; }
public string Str1 { get; set; }
public string Str2 { get; set; }
public static string Serialize(ServerData dto)
{
//Add an empty namespace and empty value
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlSerializer ser = new XmlSerializer(typeof(ServerData));
using (StringWriter textWriter = new StringWriter())
{
ser.Serialize(textWriter, dto, ns);
return textWriter.ToString();
}
}
public static ServerData Deserialize(string xml)
{
XmlSerializer ser = new XmlSerializer(typeof(ServerData));
using (var reader = new StringReader(xml))
{
return (ServerData)ser.Deserialize(reader);
}
}
}
类助手,定义用于读写字符串的数据协议:
public class StreamString
{
private Stream ioStream;
private UnicodeEncoding streamEncoding;
public StreamString(Stream ioStream)
{
this.ioStream = ioStream;
streamEncoding = new UnicodeEncoding();
}
public string ReadString()
{
byte[] strSizeArr = new byte[sizeof(int)];
ioStream.Read(strSizeArr, 0, sizeof(int));
int strSize = BitConverter.ToInt32(strSizeArr, 0);
byte[] inBuffer = new byte[strSize];
ioStream.Read(inBuffer, 0, strSize);
return streamEncoding.GetString(inBuffer);
}
public int WriteString(string outString)
{
byte[] outBuffer = streamEncoding.GetBytes(outString);
byte[] strSize = BitConverter.GetBytes(outBuffer.Length);
ioStream.Write(strSize, 0, strSize.Length);
ioStream.Write(outBuffer, 0, outBuffer.Length);
ioStream.Flush();
return outBuffer.Length + 2;
}
}
服务器代码:
[STAThread]
static void Main(string[] args)
{
Thread serverThread = new Thread(ServerThread);
serverThread.Priority = ThreadPriority.Highest;
serverThread.Start();
serverThread.Join();
}
static void ServerThread()
{
using (var server = new NamedPipeServerStream("PipesEnroll", PipeDirection.InOut, 1))
{
server.WaitForConnection();
var ss = new StreamString(server);
string terminalTemplate;
string matcherTemplate;
const int mathVersionNumber = 9;
int numberFingers;
bool isOk = Enroll.EnrollWithoutWCF(images, mathVersionNumber, out terminalTemplate, out matcherTemplate,
out numberFingers);
var dtoSend = new ServerData();
dtoSend.Result = isOk;
dtoSend.Int1 = numberFingers;
dtoSend.Str1 = terminalTemplate;
dtoSend.Str2 = matcherTemplate;
var xmlSend = ServerData.Serialize(dtoSend);
ss.WriteString(xmlSend);
server.WaitForPipeDrain();
server.Close();
}
}
客户代码:
using (
var client = new NamedPipeClientStream(".", "PipesEnroll", PipeDirection.InOut,
PipeOptions.None, TokenImpersonationLevel.Impersonation))
{
client.Connect();
var ss = new StreamString(client);
string xmlReceive = ss.ReadString();
var dtoReceived = ServerData.Deserialize(xmlReceive);
bool isOK = dtoReceived.Result;
string terminalTemplate = dtoReceived.Str1;
string matcherTemplate = dtoReceived.Str2;
int numberFingers = dtoReceived.Int1;
}
}