用于简单聊天的C#TCP服务器
我正在使用Microsoft提供的异步示例编写我的第一个TCP服务器 我从这个例子中得到了一切。我将它扩展为一个简单的聊天程序。但是我很难遵循这个程序的步骤(可能是因为它的异步性质)。当收到消息时,它会回显到客户端并关闭套接字。我看不出它回到哪里去重新打开插座用于简单聊天的C#TCP服务器,c#,sockets,tcp,C#,Sockets,Tcp,我正在使用Microsoft提供的异步示例编写我的第一个TCP服务器 我从这个例子中得到了一切。我将它扩展为一个简单的聊天程序。但是我很难遵循这个程序的步骤(可能是因为它的异步性质)。当收到消息时,它会回显到客户端并关闭套接字。我看不出它回到哪里去重新打开插座 public static void StartListening() { // Data buffer for incoming data. byte[] bytes = new Byte[1024];
public static void StartListening() {
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];
// Establish the local endpoint for the socket.
// The DNS name of the computer
// running the listener is "host.contoso.com".
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp );
// Bind the socket to the local endpoint and listen for incoming connections.
try {
listener.Bind(localEndPoint);
listener.Listen(100);
while (true) {
// Set the event to nonsignaled state.
allDone.Reset();
// Start an asynchronous socket to listen for connections.
Console.WriteLine("Waiting for a connection...");
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener );
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
private static void SendCallback(IAsyncResult ar) {
try {
// Retrieve the socket from the state object.
Socket handler = (Socket) ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = handler.EndSend(ar);
Console.WriteLine("Sent {0} bytes to client.", bytesSent);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
还有,让插座开着是不是很正常
当收到消息时,它会回显到客户端并关闭套接字。我看不出它回到哪里去重新打开插座
public static void StartListening() {
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];
// Establish the local endpoint for the socket.
// The DNS name of the computer
// running the listener is "host.contoso.com".
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp );
// Bind the socket to the local endpoint and listen for incoming connections.
try {
listener.Bind(localEndPoint);
listener.Listen(100);
while (true) {
// Set the event to nonsignaled state.
allDone.Reset();
// Start an asynchronous socket to listen for connections.
Console.WriteLine("Waiting for a connection...");
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener );
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
private static void SendCallback(IAsyncResult ar) {
try {
// Retrieve the socket from the state object.
Socket handler = (Socket) ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = handler.EndSend(ar);
Console.WriteLine("Sent {0} bytes to client.", bytesSent);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
那是因为它没有。通信完成后,服务器接收、发送回复并使用该连接完成。它只是继续等待侦听套接字上的新连接。你有一段时间(真的)。您将继续在接受呼叫中等待新的传入连接。您将为每个新客户端获得一个新套接字
还有,让插座开着是不是很正常
是,监听插座保持打开状态。它保持打开状态,以便使用accept继续接收新连接
在这里可以找到使用async和Wait编写echo服务器的更好方法:您知道如何编写阻塞echo服务器吗?如果您这样做了,那么您应该阅读有关reactor和proactor模式的内容。以下行:listener.Listen(100)。这是一个糟糕的MS示例。这里的异步IO不是真正的异步,因为它等待完成。毫无意义。@usr这很容易误导他们……所以套接字仍然打开,但与该客户端的连接已关闭?我想我真正的问题应该是,
保持与客户端的连接打开是正常的吗
,而不是套接字。你完全搞错了。侦听套接字处于侦听状态,从未在实际连接中使用。每当有传入连接时,将发生的情况是侦听套接字被克隆到一个新的套接字中,但这是一个服务套接字,属于包含此服务套接字和连接套接字的套接字对。套接字对标识连接。侦听套接字从来不是套接字对的一部分,因此它不属于任何连接。它只是用来建立联系的一种方式。请参见我的回答。如果这对你有帮助,请标记为有用或回答。好的,你的链接帖子确实很有帮助。所以我要再试一次!让服务套接字保持打开状态正常吗?:)示例代码中的服务套接字已关闭:handler.Shutdown(SocketShutdown.Both);handler.Close();具有清除请求-应答机制的Web服务器将关闭连接。同样适用于EchoServer,timeofday。但是聊天系统通常会让套接字打开更长的时间,当然这取决于它们的实现。