c#异步服务器回复

时间:2016-01-04 19:05:53

标签: c# sockets

首先,如果存在类似这样的问题,我会道歉,我在谷歌搜索并阅读可能有我答案但无法找到答案的问题。 我有以下服务器代码:

private void StartServer()
{
    try
    {
        sSocket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
        sSocket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, 0);
        sSocket.Bind(new IPEndPoint(IPAddress.Any, 6666));
        sSocket.Listen(0);
        sSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);
    }
    catch(Exception ex)
    {
        MessageBox.Show(ex.Message, "Server", MessageBoxButton.OK, MessageBoxImage.Error);
    }
}

private void AcceptCallback(IAsyncResult ar)
{
    try
    {
        cSocket = sSocket.EndAccept(ar);
        buffer = new byte[cSocket.ReceiveBufferSize];
        cSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
        sSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);
    }
    catch(Exception ex)
    {
        MessageBox.Show(ex.Message, "Server", MessageBoxButton.OK, MessageBoxImage.Error);
    }
}

private void ReceiveCallback(IAsyncResult ar)
{
    try
    {
        int received = cSocket.EndReceive(ar);

        if(received == 0)
        {
            return;
        }

        Array.Resize(ref buffer, received);
        text = Encoding.ASCII.GetString(buffer);
        DisplayText(text);
        cSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Server", MessageBoxButton.OK, MessageBoxImage.Error);
    }
}

private void DisplayText(string text)
{
    Dispatcher.BeginInvoke(new Action(delegate
    {
        textBox.Text += ">> " + text + "\r\n" + "\r\n";
    }));
}

以下客户端代码:

private void connect()
{
    try
    {
        cSocket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
        cSocket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, 0);
        cSocket.BeginConnect(new IPEndPoint(IPAddress.Parse("192.168.1.2"), 6666), new AsyncCallback(ConnectCallback), null);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Registracija", MessageBoxButton.OK, MessageBoxImage.Error);
    }
}

private void ConnectCallback(IAsyncResult ar)
{
    try
    {
        cSocket.EndConnect(ar);
        buffer = Encoding.ASCII.GetBytes("sendstuff");
        cSocket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(SendCallBack), null);
    }
    catch (SocketException) { }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Registracija", MessageBoxButton.OK, MessageBoxImage.Error);
    }
}

private void SendCallBack(IAsyncResult ar)
{
    cSocket.EndSend(ar);
}

我知道我在外部支持ip的套接字上使用本地IP。我刚刚删除了一些非重要的东西,并将本地IP隐藏在外部。所以我将客户端连接到服务器,没有问题,一切都很好,我可以毫无问题地向服务器发送数据,但我无法找到/找到如何让服务器回复客户端的东西。举个例子,我可以说我向服务器发送了一个字符串,说"我是一个字符串"。现在服务器使用该字符串执行某些操作,让我们说切断"我" m"现在它需要向客户端发送剩余的字符串"字符串"。

2 个答案:

答案 0 :(得分:0)

对于使用流来回发送的字符串,我使用StreamReaderStreamWriter,如下所示:

服务器端

using (var reader = new StreamReader(theStream))
{
    string message = reader.ReadLine();

    // Or in an async method
    string message = await reader.ReadLineAsync();
}

客户端

using (var writer = new StreamWriter(theStream))
{
    writer.WriteLine(theMessage);

    // Or in an async method
    await writer.WriteLineAsync(theMessage);
}

注意:由于您使用的是TCP,因此可以使用NetworkStream从TCP套接字获取new NetworkStream(theSocket)

答案 1 :(得分:0)

cSocket.BeginSend您呼叫DisplayText的位置如何?显然能够使用BeginSend,您需要将文本放入缓冲区。有多种方法可以有效地实现它,但它超出了这个答案的范围。

但是如果您期望某种结构化数据(例如由换行符分隔的字符串),那么最好使用StreamReader.ReadLine。如果结构更复杂,那么您需要自己从缓冲区进行解析。所以你需要从缓冲区中消耗一个字符,看看你是否有足够的数据,如果没有消耗,直到缓冲区为空。当缓冲区为空时,您需要通过调用BeginReceive再次填充它。当您有足够的数据要处理时,请使用BeginSend或其中一个流写入函数发回响应。

网络编程并非易事,您应该从互联网上查看一些示例服务器/客户端代码并彻底了解它们。最后但同样重要的是,我建议你使用await / async syntactic sugars。