Итак, в настоящее время я изучаю Сокеты , и мне удалось создать Сервер, который принимает соединения, и Клиент, который подключается к Серверу.
Когда Client
подключается к Server
Серверу, он реагирует, показывая MessageBox
, говоря "Client Connected"
. Супер просто и работает как шарм.
Однако, если я затем закрою клиент, он, как правило, выдаст SocketException
, объясняющий, что «Эй, клиент был принудительно закрыт», что понятно, довольно сложно получить какие-либо данные, когда соединение разорвано.
Итак, я реализовал функцию Socket.Poll
для определения состояния сокета, и после этого он перестал генерировать исключение, потому что теперь я его обрабатываю.
Я никогда не говорил, что сделал это хорошо, просто с этим справляются, и я обращаюсь за помощью.
Теперь, если Client
аварийно завершает работу или принудительно закрывается, он не выдает ошибку, но когда я пытаюсь подключиться снова, Server
не реагирует и не вызывает функцию Callback
.
Client
подключается к Server
, но Server
не показывает MessageBox
, к которому подключен Client
.
Почему это так?
Вот так я и начинаю
Сервер
private void StartUp()
{
ServerSocket.Bind(7777);
ServerSocket.Listen(500);
ServerSocket.AcceptConnectionAsync();
...
А вот и объект ServerSocket
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);
}
}
}
А вот так я запускаю клиент
static void Main(string[] args)
{
ClientSocket.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 7777));
while (true)
Console.Read();
}
И объект ClientSocket
class ClientSocket
{
private static readonly Socket CLIENT_SOCKET = new Socket(SocketType.Stream, ProtocolType.Tcp);
public ClientSocket()
{
}
public static void Connect(IPEndPoint Endpoint)
{
CLIENT_SOCKET.Connect(Endpoint);
if (CLIENT_SOCKET.Connected)
{
Console.WriteLine("Connected to the server.");
CLIENT_SOCKET.Send(Encoding.ASCII.GetBytes("Hello World!"), SocketFlags.None);
}
}
}