C# Socket:服务器不发送消息
C# Socket: Server doesn't send messages
我正在通过套接字进行通信,但从服务器发送数据时遇到问题。
我可以在收到内容后发送回复,但我需要能够在不事先从客户端收到任何内容的情况下发送消息。
我想做的基本上是在建立连接后通过套接字发送命令。 (在调用 AcceptCallback() 之后,我会检查)。在我的主程序中,我有一个按钮,我希望能够随时单击它来发送特定消息。但是,每次尝试此操作时,我都会收到一条错误消息,提示我无法通过未连接的套接字执行任何操作。
正如您在代码中看到的那样,我在收到来自客户端的消息后尝试发送另一条消息(请参阅 ReceiveCallback() 中我发送“测试发送”的位置)。发送有效,但如果我想在之后发送其他内容,它会再次出现错误,即我无法通过断开连接的套接字发送内容。
当前代码如下所示(摘录):
class SocketServer
{
private static Socket _serverSocket;
//Konstruktor
public SocketServer(int port = 9851)
{
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //Socket Objekt
lep = new IPEndPoint(IPAddress.Any, 9851);
}
private static void AcceptClient()
{
try
{
_serverSocket.Bind(lep);
_serverSocket.Listen(100);
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), _serverSocket); //auf Verbindungen warten weiter bei AcceptCallback Methode
}
catch
{
...
}
}
private static void AcceptCallback(IAsyncResult AR) //Connection accept callback
{
try
{
Socket socket = _serverSocket.EndAccept(AR);
socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), _serverSocket);
}
catch (ObjectDisposedException e)
{
...
}
}
private static void ReceiveCallback(IAsyncResult AR)//Weiterführung Empfangen
{
Socket socket = (Socket)AR.AsyncState;
try
{
received = socket.EndReceive(AR); //Speichere Anzahl empfangener Bytes
... //trimming and saving the received data in a string
sending = "Test send";
byte[] data = Encoding.UTF8.GetBytes(sending);
socket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallback), socket);
}
catch (ObjectDisposedException e)
{
...
}
}
public void SendMessage()
{
byte[] data = Encoding.UTF8.GetBytes(sending);
_serverSocket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallback), _serverSocket); //Beginnen des Sendevorgangs weiter bei SendCallback
...
}
private static void SendCallback(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
socket.EndSend(AR);
...
}
我已经研究这个问题一个多星期了。很难说出我以前尝试过什么,因为我觉得我已经尝试了一切,并在互联网的最深处寻找帮助。所以我站在这样的可能性面前 a) 我在某个地方非常盲目,b) 我工作过度或 c) 这实际上是不可能的,对不起 Rhino,你需要放弃你的项目并重新开始。
无论如何,如果有任何帮助,我将不胜感激。谢谢
我是这样解决问题的:
问题是我没有在与 EndAccept() 一起使用的套接字连接上使用 BeginSend(...),它只是命名为套接字。
为了能够在任何其他方法中使用此特定套接字而不仅仅是 AcceptCallback(),我必须使其可访问。
我创建了一个列表来将已接受的套接字保存在名为 _clientSockets 中,我向其中添加了每个已接受的套接字。
现在看起来像这样(只有改变的部分):
class SocketServer
{
private static Socket _serverSocket;
private static List<Sockets> _clientSockets=new List<Socket>();
private static void AcceptClient()
{
try
{
_serverSocket.Bind(lep);
_serverSocket.Listen(100);
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), _serverSocket); //auf Verbindungen warten weiter bei AcceptCallback Methode
}
catch
{
...
}
}
private static void AcceptCallback(IAsyncResult AR) //Connection accept callback
{
try
{
Socket socket = _serverSocket.EndAccept(AR);
socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), _serverSocket);
_clientSockets.Add(socket); //This is the important part where I add the completed socket connection to the list!
}
catch
{
...
}
}
public void SendMessage(string sdata, int socketno)
{
Socket socket = _clientSockets[socketno] //Here I give the socket from before, or whichever one I choose, to this method to proceed with
byte[] data = Encoding.UTF8.GetBytes(sdata);
socket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallback), socket); //Beginnen des Sendevorgangs weiter bei SendCallback
...
}
private static void SendCallback(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
socket.EndSend(AR);
...
}
我正在通过套接字进行通信,但从服务器发送数据时遇到问题。 我可以在收到内容后发送回复,但我需要能够在不事先从客户端收到任何内容的情况下发送消息。
我想做的基本上是在建立连接后通过套接字发送命令。 (在调用 AcceptCallback() 之后,我会检查)。在我的主程序中,我有一个按钮,我希望能够随时单击它来发送特定消息。但是,每次尝试此操作时,我都会收到一条错误消息,提示我无法通过未连接的套接字执行任何操作。
正如您在代码中看到的那样,我在收到来自客户端的消息后尝试发送另一条消息(请参阅 ReceiveCallback() 中我发送“测试发送”的位置)。发送有效,但如果我想在之后发送其他内容,它会再次出现错误,即我无法通过断开连接的套接字发送内容。
当前代码如下所示(摘录):
class SocketServer
{
private static Socket _serverSocket;
//Konstruktor
public SocketServer(int port = 9851)
{
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //Socket Objekt
lep = new IPEndPoint(IPAddress.Any, 9851);
}
private static void AcceptClient()
{
try
{
_serverSocket.Bind(lep);
_serverSocket.Listen(100);
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), _serverSocket); //auf Verbindungen warten weiter bei AcceptCallback Methode
}
catch
{
...
}
}
private static void AcceptCallback(IAsyncResult AR) //Connection accept callback
{
try
{
Socket socket = _serverSocket.EndAccept(AR);
socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), _serverSocket);
}
catch (ObjectDisposedException e)
{
...
}
}
private static void ReceiveCallback(IAsyncResult AR)//Weiterführung Empfangen
{
Socket socket = (Socket)AR.AsyncState;
try
{
received = socket.EndReceive(AR); //Speichere Anzahl empfangener Bytes
... //trimming and saving the received data in a string
sending = "Test send";
byte[] data = Encoding.UTF8.GetBytes(sending);
socket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallback), socket);
}
catch (ObjectDisposedException e)
{
...
}
}
public void SendMessage()
{
byte[] data = Encoding.UTF8.GetBytes(sending);
_serverSocket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallback), _serverSocket); //Beginnen des Sendevorgangs weiter bei SendCallback
...
}
private static void SendCallback(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
socket.EndSend(AR);
...
}
我已经研究这个问题一个多星期了。很难说出我以前尝试过什么,因为我觉得我已经尝试了一切,并在互联网的最深处寻找帮助。所以我站在这样的可能性面前 a) 我在某个地方非常盲目,b) 我工作过度或 c) 这实际上是不可能的,对不起 Rhino,你需要放弃你的项目并重新开始。
无论如何,如果有任何帮助,我将不胜感激。谢谢
我是这样解决问题的: 问题是我没有在与 EndAccept() 一起使用的套接字连接上使用 BeginSend(...),它只是命名为套接字。 为了能够在任何其他方法中使用此特定套接字而不仅仅是 AcceptCallback(),我必须使其可访问。 我创建了一个列表来将已接受的套接字保存在名为 _clientSockets 中,我向其中添加了每个已接受的套接字。 现在看起来像这样(只有改变的部分):
class SocketServer
{
private static Socket _serverSocket;
private static List<Sockets> _clientSockets=new List<Socket>();
private static void AcceptClient()
{
try
{
_serverSocket.Bind(lep);
_serverSocket.Listen(100);
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), _serverSocket); //auf Verbindungen warten weiter bei AcceptCallback Methode
}
catch
{
...
}
}
private static void AcceptCallback(IAsyncResult AR) //Connection accept callback
{
try
{
Socket socket = _serverSocket.EndAccept(AR);
socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), _serverSocket);
_clientSockets.Add(socket); //This is the important part where I add the completed socket connection to the list!
}
catch
{
...
}
}
public void SendMessage(string sdata, int socketno)
{
Socket socket = _clientSockets[socketno] //Here I give the socket from before, or whichever one I choose, to this method to proceed with
byte[] data = Encoding.UTF8.GetBytes(sdata);
socket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallback), socket); //Beginnen des Sendevorgangs weiter bei SendCallback
...
}
private static void SendCallback(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
socket.EndSend(AR);
...
}