这是一个用于发送数据的简单 tcpclient 示例。在演示过程中,我只发送了一个单词“test”,但发送整个xml与此相同。
c#
private void button_Click(object sender, RoutedEventArgs e)
{
Connect("127.0.0.1", "test");
}
static void Connect(String server, String message)
{
try
{
Int32 port = 13000;
TcpClient client = new TcpClient(server, port);
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
NetworkStream stream = client.GetStream();
stream.Write(data, 0, data.Length);
Console.WriteLine("Sent: {0}", message);
data = new Byte[256];
String responseData = String.Empty;
Int32 bytes = stream.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
Console.WriteLine("Received: {0}", responseData);
}
catch (ArgumentNullException e)
{
Console.WriteLine("ArgumentNullException: {0}", e);
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
}
更新:
此 xml 不是规范 xml,它缺少根节点。 我们可以修改它的格式,并使用 XmlSerializer.Deserialize 方法将其反序列化为对象并使用它。 如果我们没有修改它的权限,那么我们必须先拆分它,然后尝试处理它,如下所示:
string str = "string you received";
var delimeters = new List<string> { "<invoice"};
var addrArr = Regex.Split(str,
string.Format(@"\s+(?={0})", string.Join("|", delimeters.Select(Regex.Escape))));
foreach (var item in addrArr)
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(item);
XmlElement xmlElement = xmlDocument.DocumentElement;
Console.WriteLine(xmlElement.GetAttribute("eventid"));
Console.WriteLine(xmlElement.GetAttribute("number"));
Console.WriteLine(xmlElement.GetAttribute("processed"));
Console.WriteLine(xmlElement.FirstChild.InnerText);
}
我参考此链接以使用正则表达式。
更新 2: 假设使用 DoSomething() 方法读取所有内容。 服务器代码:
private void button_Click(object sender, RoutedEventArgs e)
{
Start2();
button.IsEnabled = false;
}
public MainWindow()
{
InitializeComponent();
}
private TcpListener listener;
public void Start2()
{
listener = new TcpListener(IPAddress.Any, 13000);
listener.Start();
Console.WriteLine("Listening...");
StartAccept();
}
private void StartAccept()
{
listener.BeginAcceptTcpClient(HandleAsyncConnection, listener);
}
private void HandleAsyncConnection(IAsyncResult res)
{
StartAccept(); //listen for new connections again
TcpClient client = listener.EndAcceptTcpClient(res);
Byte[] bytes = new Byte[1024];
string data = null;
string dataWhole = null;
NetworkStream stream = client.GetStream();
int i;
string line;
do
{
try
{
i = stream.Read(bytes, 0, bytes.Length);
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine("Received: {0}", data);
string result = DoSomething();
byte[] msg = System.Text.Encoding.ASCII.GetBytes(result);
stream.Write(msg, 0, msg.Length);
Console.WriteLine("Sent: {0}", result);
dataWhole += data;
Analyse(dataWhole);
}
catch (Exception ex)
{
Console.WriteLine("connection closed");
}
} while (stream.DataAvailable);
if (stream.DataAvailable)
{
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine("Received: {0}", data);
string result = DoSomething();
byte[] msg = System.Text.Encoding.ASCII.GetBytes(result);
stream.Write(msg, 0, msg.Length);
Console.WriteLine("Sent: {0}", result);
dataWhole += data;
Analyse(dataWhole);
}
}
client.Close();
}
public string DoSomething()
{
return "OK";
}
public void Analyse(string input)
{
//If the xml is like in the original post.
XmlSerializer serializer = new XmlSerializer(typeof(message));
using (TextReader reader = new StringReader(input))
{
message messageBody = (message)serializer.Deserialize(reader);
}
//If the xml looks like the picture in the comments.
var delimeters = new List<string> { "<invoice" };
var addrArr = Regex.Split(input,
string.Format(@"\s+(?={0})", string.Join("|", delimeters.Select(Regex.Escape))));
foreach (var item in addrArr)
{
if (!item.Contains("eventid"))
continue;
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(item);
XmlElement xmlElement = xmlDocument.DocumentElement;
Console.WriteLine(xmlElement.GetAttribute("eventid"));
Console.WriteLine(xmlElement.GetAttribute("number"));
Console.WriteLine(xmlElement.GetAttribute("processed"));
Console.WriteLine(xmlElement.FirstChild.InnerText);
}
}
更新3: 我昨天想发布回复,但发现了一个新问题。当客户端关闭时,服务器将出现异常。我添加了一些验证和尝试捕获语句。现在应该好多了。 关于问题A,是因为在测试服务器端代码的时候,客户端代码被我修改了,但是我忘了写修改,对不起。 对于问题 B,您的示例和原始帖子中的 xml 有一个消息节点,但注释中提供的图片没有这个根节点,只有三个并行发票节点,我编写的解析代码用于处理并行发票节点,因此会出现解析错误。如果 xml 中存在根节点,则 XmlSerializer 可以正确处理此 xml。我已经添加了相关代码,请检查一下。 对于静态,当前代码中不需要它。我之所以使用它,是因为我之前的示例是一个控制台应用程序,而 main 方法是静态的,因此其他方法和类字段也需要是静态的。 但在 WPF 中,这不是必需的。 根据 xml: 生成的类:
如果回复有帮助,请点击“接受答案”并点赞。 注意:如果您想接收此线程的相关电子邮件通知,请按照我们文档中的步骤启用电子邮件通知。