这是服务器端的代码:
namespace 城市燃气管网泄漏监测远程通讯系统
{
    public partial class frmTextLink : Form
    {
        public frmTextLink()
        {
            InitializeComponent();
        }        //以下是新加的
        private IPAddress myIP = IPAddress.Parse("127.0.0.1");
        private IPEndPoint MyServer;
        private Socket sock;
        private Socket handler;
        private static ManualResetEvent Done = new ManualResetEvent(false);
        //以上是新加的        private void button1_Click(object sender, EventArgs e)  //开始监听按钮
        {
            try
            {
                myIP = IPAddress.Parse(textBox1.Text);
            }
            catch { MessageBox.Show("您输入的IP格式不正确,请重新输入"); }            try
            {
                MyServer = new IPEndPoint(myIP, Int32.Parse(textBox2.Text));
                sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                sock.Bind(MyServer);
                sock.Listen(50);                toolStripStatusLabel1.Text = "  主机  " + textBox1.Text + "  端口  " + textBox2.Text + "  开始监听....";                Thread thread = new Thread(new ThreadStart(targett));
                thread.Start();            }
            catch (Exception ee)
            {
                toolStripStatusLabel1.Text = ee.Message;
            }        }        private void targett()
        {
            while (true)
            {
                //设为非终止
                Done.Reset();                //异步开始接收
                sock.BeginAccept(new AsyncCallback(AcceptCallback), sock);                //阻塞线程,知道收到信号
                Done.WaitOne();
            }
        }        private void AcceptCallback(IAsyncResult ar)
        {
            //设为终止
            Done.Set();            //获取状态
            Socket listener = (Socket)ar.AsyncState;            //结束异步接收,并获取结果
            handler = listener.EndAccept(ar);            //创建自定义类对象实例
            StateObject state = new StateObject();
            state.workSocket = handler;
            toolStripStatusLabel1.Text = "与客户建立连接";            try
            {
                byte[] byteData = System.Text.Encoding.BigEndianUnicode.GetBytes("准备完毕,可以通话!" + "\n\r");                //开始异步发送数据
                handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
            }            //定义线程
            Thread thread = new Thread(new ThreadStart(rec));            //开始接收数据线程
            thread.Start();        }        private void SendCallback(IAsyncResult ar)
        {
            try
            {
                //获取状态
                handler = (Socket)ar.AsyncState;                //结束发送
                int bytesSent = handler.EndSend(ar);
            }            catch { }
        }        private void rec()
        {
            StateObject state = new StateObject();
            state.workSocket = handler;            //开始异步接收数据
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
        }        private void ReadCallback(IAsyncResult ar)
        {
            //获取状态
            StateObject state = (StateObject)ar.AsyncState;
            Socket tt = state.workSocket;            //结束异步读取数据,并获取结果
            int bytesRead = handler.EndReceive(ar);            //贮存数据
            state.sb.Append(System.Text.Encoding.BigEndianUnicode.GetString(state.buffer, 0, bytesRead));            //转换为字符串
            string content = state.sb.ToString();            //清楚state.sb内容
            state.sb.Remove(0, content.Length);            //向richTextBox1写数据
            richTextBox1.AppendText(content + "\r\n");            //重新开始接收
            tt.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
        }        private void button3_Click(object sender, EventArgs e)  //停止监听按钮
        {
            try
            {
                sock.Close();
                toolStripStatusLabel1.Text = "  主机  " + textBox1.Text + "  端口  " + textBox2.Text + "  停止监听!";
            }
            catch
            {
                MessageBox.Show("监听尚未开始,关闭无效!");
            }
        }        private void button2_Click(object sender, EventArgs e)  //发送信息按钮
        {
            try
            {
                byte[] byteData = System.Text.Encoding.BigEndianUnicode.GetBytes(richTextBox2.Text+"\n\r");                //异步开始发送数据
                handler.BeginSend(byteData,0,byteData.Length,0,new AsyncCallback(SendCallback),handler);
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
            }
        }
    }
}客户端代码:using System.Net;  //新加的
using System.Net.Sockets;  //新加的
using System.Threading;  //新加的namespace 异步客户端
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }        private IPAddress myIP = IPAddress.Parse("127.0.0.1");
        private IPEndPoint MyServer;
        private Socket sock;
        private static ManualResetEvent connectDone = new ManualResetEvent(false);
        private static ManualResetEvent sendDone = new ManualResetEvent(false);        private void button1_Click(object sender, EventArgs e)  //请求连接
        {
            try
            {
                myIP = IPAddress.Parse(textBox1.Text);
            }
            catch { MessageBox.Show("您输入的IP格式不正确,请重新输入"); }            try
            {
                MyServer = new IPEndPoint(myIP, Int32.Parse(textBox2.Text));
                sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                sock.BeginConnect(MyServer,new AsyncCallback (ConnectCassback),sock);
                connectDone.WaitOne();
            }
            catch(Exception ee)
            {
                MessageBox.Show(ee.Message);
            }
        }        private void ConnectCassback(IAsyncResult ar)
        {
            try
            {
                //获取状态
                Socket client = (Socket)ar.AsyncState;
                client.EndConnect(ar);                //自动发送数据
                try
                {
                    byte[] byteData = System.Text.Encoding.BigEndianUnicode.GetBytes("准备完毕,可以通话!" + "\n\r");                    //异步开始发送
                    sock.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), sock);                }
                catch (Exception ee)
                {
                    MessageBox.Show(ee.Message);
                }                toolStripStatusLabel1.Text = "  主机  " + textBox1.Text + "  端口  " + textBox2.Text + " 建立连接!";                //定义线程
                Thread thread = new Thread(new ThreadStart(targett));                //开始接收线程
                thread.Start();                //设为终止
                connectDone.Set();
            }
            catch { }
        }        private void SendCallback(IAsyncResult ar)
        {
            try
            {
                //获取状态
                Socket client = (Socket)ar.AsyncState;                //设为终止
                sendDone.Set();
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
            }
        }        private void targett()
        {
            try
            {
                StateObject state = new StateObject();
                state.workSocket = sock;                //开始异步接收数据
                sock.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
            }
        }        private void ReceiveCallback(IAsyncResult ar)
        {
            try
            {
                //获取状态
                StateObject state = (StateObject)ar.AsyncState;
                Socket client = state.workSocket;                //结束异步读数据,并获取结果
                int bytesRead = client.EndReceive(ar);                //储存数据
                state.sb.Append(System.Text.Encoding.BigEndianUnicode.GetString(state.buffer, 0, bytesRead));
                string aa = state.sb.ToString();                //清除state.sb
                state.sb.Remove(0, aa.Length);                richTextBox1.AppendText(aa + "\r\n");                //读取未读数据
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);            }
            catch { }
        }        private void button2_Click(object sender, EventArgs e)   //发送信息
        {
            byte[] byteData = System.Text.Encoding.BigEndianUnicode.GetBytes(richTextBox2.Text);            //开始异步发送数据
            sock.BeginSend(byteData,0,byteData.Length,0,new AsyncCallback(SendCallback),sock);
        }        private void button3_Click(object sender, EventArgs e)   //关闭连接
        {
           
            try
            {
                sock.Close();
                toolStripStatusLabel1.Text = "  主机  " + textBox1.Text + "  端口  " + textBox2.Text + "断开连接!";            }            catch { MessageBox.Show("连接尚未建立,断开无效!"); }
        }    }
}
这是服务器端和客户端的代码。
(1)我测试用的IP是127.0.0.1, 端口6688,每次点击客户端“关闭连接”时服务器端程序就退出。不知道为什么?
(2)当我想用自己电脑的IP时,点击服务器端的“开始监听”,总是在窗体下方显示“在其上下文中,该请求的地址无效”

解决方案 »

  1.   

    或者当用自己电脑的IP时,随便用个端口号就出现异常“通常每个套接字的地址只能使用一次”(端口号是我用netstat在CMD的DOS环境中看到的),出现这个异常应该是端口冲突,那么我应该怎么样在程序中动态绑定一个可以用的端口呢?
      

  2.   

    调用socket的close的时候会引发异常。你要捕获一下异常然后进行处理。你那些回调方法里的EndXXX方法都加上捕获异常,然后做出处理。不然你close时引发的异常它不知道如何处理,所以就退出程序了。你出现异常后,Socket监听的端口没有释放,所以再运行就出现“通常每个套接字的地址只能使用一次”的异常了。
      

  3.   

    LS说的差不多了
    然后使用ShurtDown方法,从容关闭LZ最好看下一些别人写的通信程序,你的还是比较乱的