所以我目前正在学习Sockets,并且设法创建了一个接受连接的服务器和一个连接到服务器的客户端。
当Client
连接到Server
时,服务器通过显示一个MessageBox
说"Client Connected"
来做出反应。超级简单,就像魅力一样。
但是,如果我随后关闭客户端,则通常会抛出一个SocketException
,说明“嘿,客户端被强制关闭”,这是可以理解的,当断开连接时,很难接收任何数据。
所以我要做的是实现了Socket.Poll
函数来确定套接字的状态,并且这样做之后,它不再引发异常,因为我现在正在处理它。
我从来没有说过我做得很好,这只是被解决,这就是我寻求帮助的地方。
现在,如果Client
崩溃或被强制关闭,它不会引发错误,但是当我再次尝试连接时,Server
不会做出反应,也不会调用{{1 }}功能。
Callback
连接到Client
,但是Server
并未显示Server
MessageBox
已断连。
为什么会这样?
这就是我的开始方式 服务器
Client
这是ServerSocket对象
private void StartUp()
{
ServerSocket.Bind(7777);
ServerSocket.Listen(500);
ServerSocket.AcceptConnectionAsync();
...
这就是我启动客户端的方式
class ServerSocket
{
private static readonly Socket _SERVER_SOCKET = new Socket(SocketType.Stream, ProtocolType.Tcp);
private static byte[] RECEIVED_BUFFER;
public ServerSocket()
{
}
public static void Bind(int port)
{
_SERVER_SOCKET.Bind(new IPEndPoint(IPAddress.Any, port));
}
public static void Listen(int backLog)
{
_SERVER_SOCKET.Listen(backLog);
}
public static void AcceptConnectionAsync()
{
_SERVER_SOCKET.BeginAccept(ConnectionAcceptedCallback, null);
}
private static void ConnectionAcceptedCallback(IAsyncResult ar)
{
//Once this function gets invoked we can stop that specific one
//and store the socket instance in a variable.
var ACCEPTED_SOCKET = _SERVER_SOCKET.EndAccept(ar);
MessageBox.Show("Client connected.");
//Clear the BUFFER before passing it into the callback
RECEIVED_BUFFER = new byte[1024];
//Starts receiving data and store it in the BUFFER
//Once data has been received, invoke the callback.
ACCEPTED_SOCKET.BeginReceive(RECEIVED_BUFFER, 0, RECEIVED_BUFFER.Length, SocketFlags.None,
ReceivedDataCallback, ACCEPTED_SOCKET);
}
private static void ReceivedDataCallback(IAsyncResult ar)
{
//Null cast the AsyncResult parameter as a Socket.
var CLIENT_SOCKET = ar.AsyncState as Socket;
if (!CLIENT_SOCKET.Poll(1000, SelectMode.SelectRead))
{
//Used to theow an exception if the client forcibly closed.
//but it stopped since I'm using "Poll" now.
var BUFFER_SIZE = CLIENT_SOCKET.EndReceive(ar);
var PACKET = new byte[BUFFER_SIZE];
Array.Copy(RECEIVED_BUFFER, PACKET, PACKET.Length);
//Handle the packet.
MessageBox.Show($"{CLIENT_SOCKET.RemoteEndPoint}: {Encoding.ASCII.GetString(PACKET)}");
}
else
{
CLIENT_SOCKET.Disconnect(false);
}
}
}
还有ClientSocket对象
static void Main(string[] args)
{
ClientSocket.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 7777));
while (true)
Console.Read();
}