我正在通过套接字教程工作,我正在遇到问题。我有3个班级;服务器,ServerClient和客户端。服务器侦听连接请求,ServerClient是服务器端套接字包装器,客户端是尝试连接的用户端程序。
我面临的问题是,当服务器将接受的套接字传递给ServerClient类时,Socket会断开连接。如果我调试Socket传递了Connected = True,但是当我在ServerClient中设置局部变量时,它变为Connected = False。
在客户端,我没有遇到问题,但我知道Socket仍然处于连接状态。
我做错了什么,还有什么比我的代码更糟糕?
服务器:
public async void Run()
{
//
if (AcceptingClients)
{
// Error already running
return;
}
//
LoadSettings();
//
IPEndPoint localEndPoint = new IPEndPoint(_settings.Ip, _settings.Port);
// Start The Server
_server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_server.Bind(localEndPoint);
_server.Listen(100);
//
AcceptingClients = true;
//
OnServerStart(EventArgs.Empty);
// Running => Accept connections
await AcceptConnections();
// Stopped => Close connections
await CloseConnections();
// Server Stopped => Finish stuff
//
OnServerStop(EventArgs.Empty);
}
private async Task AcceptConnections()
{
await Task.Run(() =>
{
while (AcceptingClients)
{
try
{
// Set the _acceptConnectionDone to nonsignaled state.
_acceptConnectionDone.Reset();
//
_server.BeginAccept(AcceptConnectionsCallback, _server);
// Wait until a connection is made before continuing.
_acceptConnectionDone.WaitOne();
}
catch
{
//
}
}
});
}
private static void AcceptConnectionsCallback(IAsyncResult ar)
{
// Signal the AcceptConnections Task to continue.
_acceptConnectionDone.Set();
//
if (!AcceptingClients)
{
// Server Stopping or stopped
return;
}
// Get the socket that handles the client request.
Socket server = (Socket)ar.AsyncState;
Socket client = server.EndAccept(ar);
// Create the client object.
ServerClient newclient = new ServerClient(client);
// Add Events
//
_connections.TryAdd(_totalConnectionCount++, newclient);
}
ServerClient:
private readonly Socket _connection;
//
public ServerClient(Socket s)
{
//
_connection = s;
//
Run();
// Disconnected or needs to be disconnected => Process
Disconnect();
return;
}
private async void Run()
{
//
if (_connection.Connected)
{
//
_connection.ReceiveBufferSize = ServerExt.ReadBufferSize;
_connection.SendBufferSize = ServerExt.SendBufferSize;
_connection.NoDelay = true;
//
await ListenToClient();
}
}
客户端:
public async void Connect()
{
if (_connection != null)
{
// Check if we are not connected already
}
//
LoadSettings();
//
try
{
//
IPEndPoint remoteEndPoint = new IPEndPoint(_settings.Ip, _settings.Port);
// Create a TCP/IP socket.
_connection = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
{
ReceiveBufferSize = ServerExt.ReadBufferSize,
SendBufferSize = ServerExt.SendBufferSize,
NoDelay = true
};
// Connect to the remote endpoint.
_connection.Connect(remoteEndPoint);
//
if (_connection.Connected)
{
//
await ListenToServer();
}
}
catch
{
//
}
// Disconnected or needs to be disconnected => Process
Disconnect();
return;
}
日Thnx。
答案 0 :(得分:0)
我设法通过更改ServerClient的代码来保持连接打开。
public ServerClient(int id, Socket s, ClientConnectedDelegate connected, ClientDisconnectedDelegate disconnected)
{
//
Id = id;
//
_connection = s;
_disconnected = disconnected;
//
Ip = _connection.RemoteIp();
//
_connection.ReceiveBufferSize = ServerExt.ReadBufferSize;
_connection.SendBufferSize = ServerExt.SendBufferSize;
_connection.NoDelay = true;
//
_netStream = new NetworkStream(_connection, FileAccess.ReadWrite);
//
if (_cert != null)
{
_ssl = new SslStream(_netStream, false);
_ssl.AuthenticateAsServer(_cert, false, SslProtocols.Tls, true);
//
_br = new BinaryReader(_ssl, Encoding.UTF8, false);
_bw = new BinaryWriter(_ssl, Encoding.UTF8, false);
}
else
{
_br = new BinaryReader(_netStream, Encoding.UTF8, false);
_bw = new BinaryWriter(_netStream, Encoding.UTF8, false);
}
//
Task.Factory.StartNew(ListenToClient);
//
connected(this);
}