none
关于异步通信的问题 RRS feed

  • 问题

  • 我想写一个最简单的异步通信,就是把客户端的一个字符串传入服务器端,在服务器端倒序之后传回客户端显示,不知道想要实现我这种功能的异步通信是不是该这样写,而且在客户端的代码还抛出异常“未将对象引用设置到对象的实例。”,请大家指点一下,谢谢。代码如下:
    服务器端:

    namespace SimpleServer
    {
        public partial class Form1 : Form
        {
            private Thread ListenerThread;
            TcpListener tcpListener = null;
     
            public Form1()
            {
                InitializeComponent();
                ListenerThread = new Thread(new ThreadStart(ListenerThreadMethod));
                ListenerThread.IsBackground = true;
                ListenerThread.Start();
            }
     
            public void ListenerThreadMethod()
            {
                TcpClient tcpClient = null;
                NetworkStream networkStream = null;
                try
                {
                    IPAddress ip = IPAddress.Parse("127.0.0.1");
                    tcpListener = new TcpListener(ip, 7777);
                    tcpListener.Start();
                }
                catch
                {
                    MessageBox.Show("不能建立服务器");
                }
                while (true)
                {
                    try
                    {
                        tcpClient = tcpListener.AcceptTcpClient();
                        //对收到的请求做处理
                        List<byte> reData = new List<byte>();
                        byte[] reDataBytes = new byte[tcpClient.ReceiveBufferSize];
                        int n = 0;
                        networkStream = tcpClient.GetStream();
                        if (networkStream.CanRead)
                        {
                            do
                            {
                                n = networkStream.Read(reDataBytes, 0, (int)tcpClient.ReceiveBufferSize);
                                if (n == (int)tcpClient.ReceiveBufferSize)
                                    reData.AddRange(reDataBytes);
                                else if (n != 0)
                                {
                                    byte[] bytes1 = new byte[n];
                                    for (int i = 0; i < n; i++)
                                    {
                                        bytes1[i] = reDataBytes[i];
                                    }
                                    reData.AddRange(bytes1);
                                }
                            } while (networkStream.DataAvailable);
                        }
                        reDataBytes = reData.ToArray();
                        //字符串倒序
                        string reString = Encoding.UTF8.GetString(reDataBytes);
                        string tempString = "";
                        for (int i = reString.Length - 1; i >= 0; i--)
                        {
                            tempString += reString[i];
                        }
                        byte[] data = Encoding.UTF8.GetBytes(tempString);
                        networkStream.BeginWrite(data, 0, data.Length, new AsyncCallback(DownLoadCallBackF), networkStream);
                    }
                    catch
                    {
                    }
                }
            }
     
            public void DownLoadCallBackF(IAsyncResult ar)
            {
                NetworkStream networkStream = (NetworkStream)ar.AsyncState;
                try
                {
                    networkStream.EndWrite(ar);
                }
                catch
                {
                }
                finally
                {
                    if (networkStream != null)
                        networkStream.Close();
                }
            }
        }
    }

    客户端:

    namespace SimpleClient
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
     
            private void button1_Click(object sender, EventArgs e)
            {
                TcpClient tcpClient = new TcpClient();
                tcpClient.BeginConnect(IPAddress.Parse("127.0.0.1"), 7777, new AsyncCallback(DownloadCallBackF), tcpClient);
            }
     
            public byte[] ReadFromTcpClient(TcpClient tcpClient)
            {
                List<byte> data = new List<byte>();
                NetworkStream networkStream = null;
                byte[] bytes = new byte[tcpClient.ReceiveBufferSize];
                int n = 0;
                try
                {
                    networkStream = tcpClient.GetStream();
                    if (networkStream.CanRead)
                    {
                        do
                        {
                            n = networkStream.Read(bytes, 0, (int)tcpClient.ReceiveBufferSize);
                            if (n == (int)tcpClient.ReceiveBufferSize)
                                data.AddRange(bytes);
                            else if (n != 0)
                            {
                                byte[] bytes1 = new byte[n];
                                for (int i = 0; i < n; i++)
                                    bytes1[i] = bytes[i];
                                data.AddRange(bytes1);
                            }
                        } while (networkStream.DataAvailable);
                    }
                    bytes = data.ToArray();
                }
                catch
                {
                    MessageBox.Show("读取数据失败");
                    bytes = null;
                }
                finally
                {
                    if (networkStream != null)
                        networkStream.Close();
                    tcpClient.Close();
                }
                return bytes;
            }
     
            public void DownloadCallBackF(IAsyncResult ar)
            {
                TcpClient tcpClient = (TcpClient)ar.AsyncState;
                try
                {
                    tcpClient.EndConnect(ar);
                    NetworkStream netStreamSend = null;
                    byte[] netSend = new byte[textBox1.Text.Length];
                    netSend = Encoding.UTF8.GetBytes(textBox1.Text);
                    netStreamSend.BeginWrite(netSend, 0, netSend.Length, new AsyncCallback(SendCallBackF), netStreamSend);
                }
                //此处捕获异常“未将对象引用设置到对象的实例。”
                catch
                {
                    MessageBox.Show("连接失败");
                    return;
                }
                byte[] bytes = ReadFromTcpClient(tcpClient);
                textBox2.Text = Encoding.UTF8.GetString(bytes);
            }
     
            public void SendCallBackF(IAsyncResult ar)
            {
                NetworkStream netStream = (NetworkStream)ar.AsyncState;
                try
                {
                    netStream.EndWrite(ar);
                }
                catch
                {
                }
                finally
                {
                    if (netStream != null)
                        netStream.Close();
                }
            }
        }
    }




    • 已编辑 Nav7SL 2013年4月7日 6:21
    2013年4月7日 6:21

答案

全部回复

  • 首先请启动服务端,然后启动客户端。

    关于你抛出异常的问题:你自己把NetWorkStream设置成了空,自然得不到而且抛出异常了。

    try
                {
                    tcpClient.EndConnect(ar);
                    NetworkStream netStreamSend = null;
                    byte[] netSend = new byte[textBox1.Text.Length];
                    netSend = Encoding.UTF8.GetBytes(textBox1.Text);
                    netStreamSend.BeginWrite(netSend, 0, netSend.Length, new AsyncCallback(SendCallBackF), netStreamSend);
                }

    仔细看:netStreamSend=null,不能调用BeginWrite方法了。


    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats

    2013年4月7日 6:38
    版主
  • 请问这个该怎么改呢?我用的TcpClient 无法填入socket对象啊

    try
    {
        tcpClient.EndConnect(ar);
        NetworkStream netStreamSend = new NetworkStream(这里需要填如socket对象 但是我用的是TcpClient);
        byte[] netSend = new byte[textBox1.Text.Length];
        netSend = Encoding.UTF8.GetBytes(textBox1.Text);
        netStreamSend.BeginWrite(netSend, 0, netSend.Length, new AsyncCallback(SendCallBackF), netStreamSend);
     }

    2013年4月7日 7:33
  • GetStream()方法。

    NetworkStream netStreamSend = tcpClient.GetStream();

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats

    2013年4月7日 8:49
    版主