我正在构建一个简单的代理,它将记录通过它传递的某些请求。代理不需要干扰通过它的流量(在项目的这一点上),因此我尝试在处理过程中尽可能少地解析原始请求/响应(请求和响应被推送)到要在代理外部记录的队列)。
我的示例工作正常,但无法可靠地判断“响应”何时完成,因此我的连接保持打开状态的时间超过了所需的时间。相关代码如下:
var request = getRequest(url);
byte[] buffer;
int bytesRead = 1;
var dataSent = false;
var timeoutTicks = DateTime.Now.AddMinutes(1).Ticks;
Console.WriteLine(" Sending data to address: {0}", url);
Console.WriteLine(" Waiting for response from host...");
using (var outboundStream = request.GetStream()) {
while (request.Connected && (DateTime.Now.Ticks < timeoutTicks)) {
while (outboundStream.DataAvailable) {
dataSent = true;
buffer = new byte[OUTPUT_BUFFER_SIZE];
bytesRead = outboundStream.Read(buffer, 0, OUTPUT_BUFFER_SIZE);
if (bytesRead > 0) { _clientSocket.Send(buffer, bytesRead, SocketFlags.None); }
Console.WriteLine(" pushed {0} bytes to requesting host...", _backBuffer.Length);
}
if …Run Code Online (Sandbox Code Playgroud) 我正在阅读这篇文章,并在解决方案中注意到,如果您发送与实际数据分开的数据长度,Nagle 的算法可能会发挥作用并使发送的数据不同步。
我想知道这一点,因为我看到很多代码示例客户端首先发送数据的长度,然后发送数据本身以进行单独的调用。这个问题对他们没有影响吗?
我是否应该将数据的长度和数据本身连接到一个字节数组中并一次性发送?如果是这样,是否有一种更好的方法来连接两个字节数组,而无需手动将两个(循环)中的所有数据复制到新数组中?对于经常发生的事情(每次用户或服务器在彼此之间发送数据时)来说,似乎效率很低。
当我试图避免使用Thread.sleep(400)
我的代码时遇到问题,如下所示:
System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
clientSocket = Connect(IP, Port);
Thread.Sleep(400);
NetworkStream networkStream = clientSocket.GetStream();
Send(networkStream, "My Data To send");
networkStream.Flush();
Run Code Online (Sandbox Code Playgroud)
和我的 send() 方法:
public static void Send(NetworkStream networkStream, string Data)
{
int range = 1000;
int datalength = 0;
foreach (string data in Enumerable.Range(0, Data.Length / range).Select(i => Data.Substring(i * range, range)))
{
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(data);
networkStream.Write(outStream, 0, outStream.Length);
datalength = datalength + range;
Thread.Sleep(50);
}
byte[] LastoutStream = System.Text.Encoding.ASCII.GetBytes(Data.Substring(datalength, Data.Length - datalength) + "$EOS$\r\n");
networkStream.Write(LastoutStream, …Run Code Online (Sandbox Code Playgroud) 我正在使用 nmodbus 库(从 Google 代码下载)通过 TCP 进行 modbus rtu 通信。
我正在使用硬件(RS485 到以太网转换器)将我的 modbus over RTU 请求转换为 TCP,反之亦然。
如果我发送请求并且 modbus 设备处于活动状态,则一切正常,但是如果我发送请求并且 modbus 设备未处于活动状态,则我的 tcpclient 连接会自动关闭,我希望它保持打开状态并抛出超时异常,但这没有发生。
我已经正确设置了超时值,但仍然没有结果。
我的示例伪代码如下
using (TcpClient _client = new TcpClient(ipAdd, 1025))
{
_client.NoDelay = true;
ModbusSerialMaster _device = ModbusSerialMaster.CreateRtu(tcpObj);
_device.Transport.ReadTimeout = 1000;
_device.Transport.WriteTimeout = 1000;
_device.ReadInputRegisters(meterID, startAdd, register);
}
Run Code Online (Sandbox Code Playgroud)
我已经使用modbus模拟器(Pollscan,modbus poll)验证了转换器和modbus硬件的功能
我相信我在设置 tcpclient 的属性时犯了一些错误,但不确定到底是什么。
任何建议、意见都非常值得赞赏。
我编写了一个简单的 .Net 客户端,它通过 TCP/IP 连接到硬件设备 (FPGA)。当我单击客户端中的按钮时,它会向设备发送一个小的(4 字节)“请求”,然后立即读取设备响应的数据块(约 32kb)。客户端代码如下所示:-
var stream = _tcpClient.GetStream();
stream.Write(requestData, 0, requestData.Length);
using (var ms = new MemoryStream())
{
var tempBuffer = new byte[65535];
do
{
var numBytesRead = stream.Read(tempBuffer, 0, tempBuffer.Length);
ms.Write(tempRead, 0, numBytesRead);
}
while(ms.Length < ExpectedResponseSize);
_hardwareResponse = ms.ToArray();
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中使用秒表通常会报告 2-3ms 来读取整个 32kb 响应,如果我反复缓慢单击按钮(例如每秒一次),这个时间会保持一致。
如果我开始更快速地点击按钮(例如每半秒),那么几秒钟后时间会突然下降到大约 12 毫秒并保持在那里,即使我回到缓慢点击按钮。如果我关闭然后重新打开客户端上的连接并重试,它会回到 2-3 毫秒的时间。
WireShark 显示在更快的响应期间从 PC 发出 3-4 个 ACK,但一旦时间下降到 12 毫秒,这会增加到十几个或更多。在这两种情况下,来自 FPGA 的数据包的数量和大小是相同的。我尽可能自信地认为客户端或 FPGA 上的代码没有问题(两者都不会变得更简单) - 直觉是它是协议或网络的事情。有什么想法吗?
尝试在 Node.js 应用程序中发送纯文本消息,就像我从终端使用“nc”发送纯文本消息一样,即
echo "a.random.test" | nc -v <some_domain> <some_port>
Run Code Online (Sandbox Code Playgroud)
然而却无法这样做。我尝试使用 const 'netcat/client' npm 模块,但没有成功。这是该模块的文档链接https://github.com/roccomuso/netcat,下面是我当前的一些尝试。似乎已建立连接(由于回调触发而确认),但是消息中存在额外的填充,并且我预期的“a.random.test”明文消息并未按原样接收“a.random.test”。
const nclient = require('netcat/client')
const nc2 = new nclient()
nc2
.addr('x.x.x.x') // the ip
.port(2003) // the port
.connect()
.send(`a.random.test`, () => console.log(`connection made and message sent`))
Run Code Online (Sandbox Code Playgroud)
我也尝试过下面好的“网络”模块插座,但没有成功。
var net = require('net');
var client = new net.Socket();
client.connect(2003, 'x.x.x.x', function() {
console.log(`sending to server: a.random.test`)
client.write(`a.random.test`)
});
Run Code Online (Sandbox Code Playgroud)
任何将纯文本发送到 Node.js 中给定端口的帮助都将不胜感激......我觉得这应该很容易 - 我花费的时间比我愿意承认的尝试这样做的时间要多!预先非常感谢您。
我正在将一些 C++ 移植到 C#。我正在努力寻找各种套接字选项的等效项。我无法弄清楚的是如何TCP_QUICKACK在 C# 中进行设置。
如果我有一个TcpClient,那么 C# 相当于:
optval = 1;
setsockopt(socket_, IPPROTO_TCP, TCP_QUICKACK, &optval, sizeof(optval));
Run Code Online (Sandbox Code Playgroud)
在 中似乎没有等价物,在SocketOptionName中似乎也没有相应的属性TcpClient.Client。
如何设置此选项?
请注意,请参阅此链接。
我编写了这个类,用作服务器端的代理和客户端的客户端。
我当前的源代码如下:
public class ClientClass : IDisposable
{
private string Host { get; set; }
private int Port { get; set; }
public bool IsConnected { private set; get; }
public TcpClient Tcp { get; private set; }
private System.Net.Sockets.NetworkStream stream;
public ClientClass()
{
IsConnected = false;
}
//constructor for server program.
public ClientClass(TcpListener listener)
{
Tcp = listener.AcceptTcpClient();
Host = ((IPEndPoint)Tcp.Client.RemoteEndPoint).Address.ToString();
Port = ((IPEndPoint)Tcp.Client.LocalEndPoint).Port;
IsConnected = true;
stream = Tcp.GetStream();
}
//constructor for client.
public ClientClass(string …Run Code Online (Sandbox Code Playgroud) 这是我的第一个问题之一.每当我退出程序时,tcpClient.Connect()都会永远关闭.我尝试了很多东西,但似乎都没有.
看一下CreateConnection()线程,如果客户端还没有连接......我关闭程序,它需要永远关闭.如果已连接,则立即关闭.我知道这可以通过某种超时技巧来完成,但我已经尝试了一些,但没有一个工作.
如果可以,请提供代码示例.
另外,C#在读取/写入实际字节时是否有一个很好的教程,而不是只有masterServer.writeLine()和masterServer.readline()的版本,或者它们都同样有效吗?
如果你看到其他任何东西可以帮助我改善这一点......无论如何,请继续.我正在努力教自己如何做到这一点,我没有任何帮助,所以如果你看到它,不要让我继续做错事!多谢你们!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
namespace RemoteClient
{
public partial class Form1 : Form
{
private int MyPort = 56789;
private IPAddress myIp = IPAddress.Parse("210.232.115.79");
private IPAddress serverIp = IPAddress.Parse("72.216.18.77"); // Master Server's IP Address
public static TcpClient masterServer = new TcpClient();
private StreamWriter responseWriter;
private StreamReader commandReader;
private Thread connectionThread;
private Thread commandsThread;
private bool …Run Code Online (Sandbox Code Playgroud) 我有这个TcpClient代码,工作正常.它连接到Linux系统上的perl服务器并接收服务器发送给它的任何东西.很好地工作.
public static void Main() {
foreach (ProtocolConnection tcpConnection in TcpConnectionsList) {
ProtocolConnection connection = tcpConnection;
ThreadPool.QueueUserWorkItem(_ => {
ThreadTcpClient(connection);
ManualResetEventTcp.Set();
});
}
... Some code...
}
public static void TcpConnect(ProtocolConnection varConnection) {
int retryCountSeconds = varConnection.RetryEverySeconds*Program.MilisecondsMultiplier;
int count = 0;
while (true) {
try {
using (var client = new TcpClient(varConnection.IpAddress.ToString(), varConnection.Port) { NoDelay = true })
using (var stream = client.GetStream()) {
var data = new Byte[256];
while (!Program.PrepareExit) {
Int32 bytes = stream.Read(data, 0, data.Length);
string varReadData …Run Code Online (Sandbox Code Playgroud)