我正在開發一個將接收消息並作出響應的服務器應用程序。沒有什麼新東西。所以,其實我跟着this answer和this post,但我不能讓AcceptAsync()
方法觸發Completed
事件。在互聯網上到處搜索,嘗試類似問題的解決方案,但似乎沒有任何工作適合我。爲什麼Socket.AcceptAsync未觸發SocketAsyncEventArgs完成的事件?
我也嘗試從Task.Run()
打電話server.Start()
,但沒有運氣。我知道服務器聽的很好,因爲我可以在netstat -an
上看到它,如果我在Listen()
之後中斷,我也可以使用telnet進行連接。
從我的理解,如果AcceptAsync()
方法返回true,它會提高SocketAsyncEventArgs.Completed
事件,這將再次調用StartAccept()
方法,並將循環,直到我強制退出。
SocketAsyncEventArgs.Completed
也對:http://prntscr.com/8l3x8p,但仍然不起作用。
這裏是我的一段代碼:
public class TTSServer
{
private Socket m_serverSocket;
private IPEndPoint m_serverEndPoint;
[DefaultValue(39454)]
public int Port { get; set; }
[DefaultValue(100)]
public int IncommingQueueSize { get; set; }
[DefaultValue(512)]
public int BufferSize { get; set; }
//Listeners to hold event when something happens.
public static void Main(string[] args)
{
TTSServer server = new TTSServer(39454, 100, 512);
server.Start();
}
public TTSServer(int port, int queueSize, int bufferSize)
{
Port = port;
IncommingQueueSize = queueSize;
BufferSize = bufferSize;
}
public void Start()
{
Console.WriteLine("Starting TTS Server (Port: {0}, QueueSize: {1}, BufferSize: {2})", Port, IncommingQueueSize, BufferSize);
m_serverEndPoint = new IPEndPoint(IPAddress.Any, Port);
m_serverSocket = new Socket(m_serverEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
Console.WriteLine("Binding ({0})", m_serverEndPoint.ToString());
m_serverSocket.Bind(m_serverEndPoint);
Console.WriteLine("Listening");
m_serverSocket.Listen(IncommingQueueSize);
StartAccept(null);
}
public void Stop()
{
}
/// <summary>
/// Receive a incomming connection attemp in an asynchronous way.
/// </summary>
/// <param name="socketEvent">If is null, a new object is created, else, it'll be used for cache friendly reason.</param>
private void StartAccept(SocketAsyncEventArgs socketEvent)
{
//If received reference points to null, let's create a new object.
if (socketEvent == null)
{
Console.WriteLine("Accepting new connections...");
socketEvent = new SocketAsyncEventArgs();
socketEvent.Completed += AcceptCompleted; //Add a callback on completed accept incomming connections attemp.
}
else
{
//Clear current incomming connection socket, so object may be reused.
socketEvent.AcceptSocket = null;
}
//If there is an incomming connection pending(pooled), this method will receive the connection in a async way (witch returns true)
//and will call SocketAsyncEventArgs.Completed callback when done.
//Else, it waits for a new connection, returns false, and don't won't SocketAsyncEventArgs.Completed callback when done, so we have to
//call it manually.
bool async = true;
//When I debug this code, async receive true from AcceptAsync.
async = m_serverSocket.AcceptAsync(socketEvent);
if (!async)
{
AcceptCompleted(this, socketEvent);
}
}
/// <summary>
/// Handles a incomming connection after it's fully received. This function will do the business logic for incomming connections and prepare
/// to receive data.
/// </summary>
/// <param name="sender">Object who posted this function</param>
/// <param name="socketEvent">Information of the incomming connection</param>
private void AcceptCompleted(object sender, SocketAsyncEventArgs socketEvent)
{
Connection connection = new Connection(this, socketEvent.AcceptSocket, BufferSize);
SocketAsyncEventArgs connectedSocketEvent = new SocketAsyncEventArgs();
connectedSocketEvent.UserToken = connection;
//Add a receive callback, to be called whenever the Receive function is finished.
connectedSocketEvent.Completed += FlushBuffer;
ReceiveData(connectedSocketEvent);
//Accept next incomming connection.
StartAccept(socketEvent);
}
不知道爲什麼,在AcceptCompleted
是從來沒有發射,即使AcceptAsync()
方法返回true
。
這不是一個答案,但真正的問題是沒有實際意義。您應該通過在APM模式中使用await包裝來開發套接字應用程序。根本不要使用socketeventargs。所有這些都已經過時了。使用網上現成的包裝。問題將會消失。也不是99%的套接字教程被破壞或被誤導。 – usr
你會推薦我嗎? –
您只需要添加等待Socket的東西。這是幾十行代碼。 – usr