如何使用套接字侦听器类解决性能问题?
本文关键字:性能 问题 解决 何使用 套接字 侦听器 | 更新日期: 2023-09-27 18:12:15
我是TCP/IP编程新手。我使用微软文档和我在网上找到的一个示例创建了一个侦听器。
我已经创建了一个程序,该程序使用本地IP侦听端口。
当消息最终进入时,程序立即达到100%加载并停留在那里,不幸的是我不知道停止它的方法。我假设我必须使用ManualResetEvent
,但当我试图实现这一点,网页只是不加载。
我的实现如下:(端口是一个随机端口,如果有人想知道)
public static class Listener
{
private const int bufferSize = 2048;
private static byte[] buffer = new byte[bufferSize];
private static Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public static void StartListening()
{
//Gets local machine IP address
string ip = GetLocalIPAddress();
//Creates the IPADDRESS
IPAddress ipAddress = IPAddress.Parse(ip);
//Creates a local end point for .Bind(xxx)
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 1322);
Socket listenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
//Binds to local machines IP with port 1322
listener.Bind(localEndPoint);
//Places socket in a listening state
listener.Listen(0);
listener.BeginAccept(new AsyncCallback(AcceptCallback), null);
}
catch (Exception e)
{
//Throw exception
}
}
private static void CloseSocket()
{
listener.Shutdown(SocketShutdown.Both);
listener.Close();
}
public static void AcceptCallback(IAsyncResult ar)
{
//Socket casted to async state
Socket listenerSocket = (Socket)ar.AsyncState;
try
{
//Try end accept
listenerSocket = listener.EndAccept(ar);
}catch(Exception e)
{
//Throw exception
}
//Receive data
listenerSocket.BeginReceive(buffer, 0, bufferSize, SocketFlags.None, new AsyncCallback(ReadCallBack), listenerSocket);
listener.BeginAccept(new AsyncCallback(AcceptCallback), null);
}
public static void ReadCallBack(IAsyncResult ar)
{
Socket listenerSocket = (Socket)ar.AsyncState;
int received = 0;
try
{
//Amount of bytes that has been sent
received = listenerSocket.EndReceive(ar);
}catch(Exception e)
{
listener.Close();
}
//Create byte array for encoding
byte[] bytes = new Byte[received];
Array.Copy(buffer,bytes,received);
string recievedMessage = Encoding.ASCII.GetString(bytes);
if (received > 0)
{
//do task input
System.Diagnostics.Debug.WriteLine(recievedMessage);
}
//work on this
listenerSocket.BeginReceive(buffer, 0 , bufferSize, SocketFlags.None, new AsyncCallback(ReadCallBack), listenerSocket);
}
private static string GetLocalIPAddress()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
throw new Exception("Local IP Address Not Found!");
}
谢谢你的帮助
一些问题
-
你没有将监听器套接字传递给BeginAccept。
listener.BeginAccept(new AsyncCallback(AcceptCallback), null);
和
Socket listenerSocket = (Socket)ar.AsyncState;
-
你为什么要读
Socket listenerSocket = (Socket)ar.AsyncState;
?? -
你在
StartListening
方法中构造了一个listenerSocket
,但是你没有使用它。
错误
当你关闭'listener' (ServerClientSocket),你不应该再调用BeginReceive
。就return
.
当received == 0
socket关闭时,所以不要启动BeginReceive
。这就是它永远循环的原因……Begin/End接收直接返回received
== 0
public static void ReadCallBack(IAsyncResult ar)
{
Socket listenerSocket = (Socket)ar.AsyncState;
int received = 0;
try
{
//Amount of bytes that has been sent
received = listenerSocket.EndReceive(ar);
}catch(Exception e)
{
received = 0;
}
if(received == 0)
{
listener.Close();
return;
}
//Create byte array for encoding
byte[] bytes = new Byte[received];
Array.Copy(buffer,bytes,received);
string recievedMessage = Encoding.ASCII.GetString(bytes);
if (received > 0)
{
//do task input
System.Diagnostics.Debug.WriteLine(recievedMessage);
}
//work on this
listenerSocket.BeginReceive(buffer, 0 , bufferSize, SocketFlags.None, new AsyncCallback(ReadCallBack), listenerSocket);
}
注意
TCP/IP套接字是流套接字,所以你永远不会知道你是否收到了一个完整的数据包或甚至两个。您需要知道您已经收到了完整的消息。通常使用PreLength协议。写一个值,表示后面的数据量
我看到你正在传递0作为Socket的参数。Listen方法,不确定这是否是导致问题的原因但值得尝试将其更改为100
public void Listen(int backlog)
int backlog:等待连接队列的最大长度。
msdn: https://msdn.microsoft.com/nl-nl/library/system.net.sockets.socket.listen (v = vs.110) . aspx