【发布时间】:2021-02-19 16:23:45
【问题描述】:
我正在通过套接字进行通信,但在从服务器发送数据时遇到问题。 我可以在收到内容后发送响应,但我需要能够发送消息而无需事先从客户端接收任何内容。
我想要做的基本上是在建立连接后通过套接字发送命令。 (在调用 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,你需要放弃你的项目并重新开始。
无论如何,我将不胜感激任何形式的帮助。谢谢。
【问题讨论】:
-
_serverSocket是为接受新连接而打开的。它与(End)Accept调用返回的任何单个套接字无关,因此与任何已建立的连接无关。换句话说,您希望哪个客户端收到“消息”? -
对不起。你能详细说明一下吗?
-
一台服务器通常为多个客户端提供服务——当然,您的代码是通过在
_serverSocket上重复调用Accept来设置的。这是与您的EndAccept调用返回的一个不同 套接字,它代表与这些客户端之一的单独连接。如果您想向(一个|所有)客户端发送消息,您需要保持对 那些 套接字的引用可用。 -
(但也请注意为什么我在第一个响应中引用了“消息” - TCP 不是消息传递系统,它是连续的字节流。如果您想要消息,则由您来介绍某种类型的消息框架(例如,在实际消息前面加上即将到来的字节数))
-
你做的不正常。客户端是主机,服务器是从机。 slave3 并不意味着在没有命令的情况下执行任务。在客户端连接之前,服务器如何知道客户端的IP地址。