使用 TcpClient 通过网络发送和接收数据
我需要开发一个连接到 TCP 服务器的服务。主要任务是读取传入消息并在十分钟内向服务器发送命令,例如同步命令。例如,我使用了 TcpClient 对象,如下所示:
...
TcpClient tcpClient = new TcpClient();
tcpClient.Connect("x.x.x.x", 9999);
networkStream = tcpClient.GetStream();
clientStreamReader = new StreamReader(networkStream);
clientStreamWriter = new StreamWriter(networkStream);
while(true)
{
clientStreamReader.Read()
}
另外,当我需要在任何方法中写出某些内容时,我使用:
clientStreamWriter.write("xxx");
这种用法正确吗?或者有更好的方法吗?
I need to develop a service that will connect to a TCP server. Main tasks are reading incoming messages and also sending commands to the server in ten minutes, like a synchronize command. For example, I used the TcpClient object as shown below:
...
TcpClient tcpClient = new TcpClient();
tcpClient.Connect("x.x.x.x", 9999);
networkStream = tcpClient.GetStream();
clientStreamReader = new StreamReader(networkStream);
clientStreamWriter = new StreamWriter(networkStream);
while(true)
{
clientStreamReader.Read()
}
Also, when I need to write out something in any method, I use:
clientStreamWriter.write("xxx");
Is this usage correct? Or is there a better way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
首先,我建议您使用 WCF、.NET Remoting 或其他一些更高级别的通信抽象。 “简单”套接字的学习曲线几乎与 WCF 一样高,因为直接使用 TCP/IP 时存在许多不明显的陷阱。
如果您决定继续沿着 TCP/IP 路径前进,请查看我的 .NET TCP/IP 常见问题解答,特别是有关消息框架 和应用程序协议规范。
另外,使用异步套接字 API。同步 API 无法扩展,在某些错误情况下可能会导致死锁。同步 API 只需要很少的示例代码,但实际生产质量的代码使用异步 API。
First, I recommend that you use WCF, .NET Remoting, or some other higher-level communication abstraction. The learning curve for "simple" sockets is nearly as high as WCF, because there are so many non-obvious pitfalls when using TCP/IP directly.
If you decide to continue down the TCP/IP path, then review my .NET TCP/IP FAQ, particularly the sections on message framing and application protocol specifications.
Also, use asynchronous socket APIs. The synchronous APIs do not scale and in some error situations may cause deadlocks. The synchronous APIs make for pretty little example code, but real-world production-quality code uses the asynchronous APIs.
请注意 - 这是一个非常古老且麻烦的“解决方案”。
顺便说一下,您可以使用序列化技术来发送字符串、数字或任何支持序列化的对象(大多数.NET 数据存储类和结构都是[Serialized])。
在那里,您应该首先将四个字节的 Int32 长度发送到流,然后将二进制序列化 (System.Runtime.Serialization.Formatters.Binary.BinaryFormatter) 数据发送到其中。
在另一侧或连接(实际上在两侧),您明确应该有一个 byte[] 缓冲区,当数据到来时,您将在运行时追加和修剪左侧。
我正在使用类似的东西:
这只是一个示例,您应该对其进行编辑以供使用。
Be warned - this is a very old and cumbersome "solution".
By the way, you can use serialization technology to send strings, numbers or any objects which are support serialization (most of .NET data-storing classes & structs are [Serializable]).
There, you should at first send Int32-length in four bytes to the stream and then send binary-serialized (System.Runtime.Serialization.Formatters.Binary.BinaryFormatter) data into it.
On the other side or the connection (on both sides actually) you definetly should have a byte[] buffer which u will append and trim-left at runtime when data is coming.
Something like that I am using:
That is just an example, you should edit it for your use.
我很幸运直接使用套接字对象(而不是 TCP 客户端)。我创建了一个看起来像这样的服务器对象(为了简洁起见,我编辑了一些内容,例如异常处理,但我希望这个想法能够实现。)...
然后,我使用一个单独的 Connection 类来管理单个连接与远程主机的连接。看起来像这样...
您可以使用 Connection 对象通过直接调用其 Socket 来发送数据,就像这样...
正如我所说,我尝试在这里编辑代码以进行发布,所以如果有的话我深表歉意其中的任何错误。
I have had luck using the socket object directly (rather than the TCP client). I create a Server object that looks something like this (I've edited some stuff such as exception handling out for brevity, but I hope that the idea comes across.)...
Then, I use a separate Connection class to manage the individual connection with the remote host. That looks something like this...
You can use your Connection object to send data by calling its Socket directly, like so...
As I said, I've tried to edit the code here for posting, so I apologize if there are any errors in it.
首先,TCP 不保证您发送的所有内容都会在另一端以相同的读取方式收到。它仅保证您发送的所有字节都将以正确的顺序到达。
因此,从流读取时需要不断建立缓冲区。您还必须知道每条消息有多大。
最简单的方法是使用不可输入的 ASCII 字符来标记数据包的结尾,并在接收到的数据中查找它。
First of all, TCP does not guarantee that everything that you send will be received with the same read at the other end. It only guarantees that all bytes that you send will arrive and in the correct order.
Therefore, you will need to keep building up a buffer when reading from the stream. You will also have to know how large each message is.
The simplest ever is to use a non-typeable ASCII character to mark the end of the packet and look for it in the received data.