有多個帖子描述了保持 TCP 連接打開的性能優勢,而不是每次需要讀取或寫入時關閉和打開。例如:
最佳實踐:每次傳輸后保持 TCP/IP 連接打開還是關閉?
我正在與采用 json 命令的基于 RPC 的設備進行通信。我從設備供應商那里獲得的示例每次發送命令時都會打開和關閉連接。這是我目前在 using 陳述句中通過 TcpClient 執行的操作,但我想看看是否可以改進我已經完成的操作。事實上,我在開始專案時已經嘗試過這個,但無法弄清楚如何去做,所以每次都出于沮喪和必要而關閉。我最近使用套接字進行的實驗,因為所有帖子都表明這樣做是低級別控制的必要條件:
public class Connection
{
private Socket tcpSocket = null;
public string IpAddress = "192.168.0.30";
public int Port = 50002;
public Connection(string ipAddress, int port)
{
this.IpAddress = ipAddress;
this.Port = port;
}
public void Connect()
{
DnsEndPoint ipe = new DnsEndPoint(this.IpAddress, this.Port);
Socket tempSocket =
new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
tempSocket.Connect(ipe);
if (tempSocket.Connected)
{
this.tcpSocket = tempSocket;
this.tcpSocket.NoDelay = true;
this.tcpSocket.
//this.tcpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive,true);
Console.WriteLine("Successfully connected.");
}
else
{
Console.WriteLine("Error.");
}
}
public void Disconnect()
{
this.tcpSocket.Disconnect(true);
this.tcpSocket.Dispose();
Console.WriteLine("Successfuly closed.");
}
public string SendCommand()
{
string path = @"C:\Users\me\Desktop\request.json";
string request = File.ReadAllText(path);
Byte[] bytesSent = Encoding.UTF8.GetBytes(request);
this.tcpSocket.Send(bytesSent);
this.tcpSocket.Shutdown(SocketShutdown.Send);
var respBytes = ReceiveAll();
string s = System.Text.Encoding.UTF8.GetString(respBytes, 0, respBytes.Length);
return s;
}
public byte[] ReceiveAll()
{
var buffer = new List<byte>();
var currByte = new Byte[1];
var byteCounter = this.tcpSocket.Receive(currByte, currByte.Length, SocketFlags.None);
while (this.tcpSocket.Available > 0)
{
currByte = new Byte[1];
byteCounter = this.tcpSocket.Receive(currByte, currByte.Length, SocketFlags.None);
if (byteCounter.Equals(1))
{
buffer.Add(currByte[0]);
}
}
return buffer.ToArray();
}
}
控制臺應用程式:
static void Main(string[] args)
{
Connection s = new Connection();
s.Connect();
Console.WriteLine(s.SendCommand());
Console.WriteLine(s.SendCommand());
Thread.Sleep(5000);
s.Disconnect();
Console.ReadKey();
}
這種方法只適用一次。我第一次呼叫發送命令。它不是第二次(拋出例外),因為我在 SendCommand() 中的 Send 上呼叫了 socket.Shutdown()。我這樣做是因為這篇文章:
TCPClient收不到資料
However, there doesn't seem to be a way to re-enable the ability to Send after calling Shutdown(). So now I just don't know if it's even possible to keep a tcp connection open if you have to both read and write. Moreover, I can't really find a useful example online. Does anyone know how to do so in .NET? Is this even possible?
uj5u.com熱心網友回復:
TCP/IP 是一種流媒體協議。要通過它傳遞訊息,您需要一個“幀協議”,以便對等方可以確定訊息何時完成。
表示訊息結束的一種簡單方法是在發送最后一個位元組后關閉套接字。但這會阻止套接字重用。有關此示例,請參閱 HTTP 的演變。
如果這是您的設備所做的,則無法重用套接字。
uj5u.com熱心網友回復:
是否可以為更多訊息保持連接打開取決于應用程式協議。如果協議不支持,則無法強制執行此操作。因此,請詢問供應商或查看協議規范(如果存在)以了解是否支持以及如何支持。
但是,似乎沒有辦法在呼叫 Shutdown() 后重新啟用發送功能。
不可能。TCP 寫關閉意味著不想再發送任何資訊。這是不可能收回的。如果協議支持多個訊息交換,那么它需要有一種與呼叫 Shutdown 不同的方法來檢測訊息的結束。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/344042.html
