当前位置:编程学习 > C#/ASP.NET >>

c# Socket通信

   (1) 我做了一个服务器工程和客户机工程,使用异步SOCKET,当同时运行两个工程的时候,进行通信

  每次点击客户端的“关闭连接”按钮时,服务器端就跳出程序,不再执行,不知道是为什么?

(2)当我将服务器端和客户端放置在一个对话框上时,不能相互发送数据,同时也当“关闭连接”时,程序退出!
--------------------编程问答-------------------- ...这样没人知道为什么

都看不到代码,你让人在这猜呀。。。 --------------------编程问答-------------------- “服务器端和客户端放置在一个对话框上时”这是什么意思啊?怎么放啊?不太明白你的意思。
你的“关闭连接”又是怎么写的?
你点击"关闭连接"时程序退出,有可能是出错了。程序就强制结束啊。
你调试一下啊。

还有听你这么描述,别人看不到代码,是无法帮你的。别人都不知道你是怎么写的。 --------------------编程问答--------------------
这是服务器端的代码:
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时,点击服务器端的“开始监听”,总是在窗体下方显示“在其上下文中,该请求的地址无效”

--------------------编程问答-------------------- 或者当用自己电脑的IP时,随便用个端口号就出现异常“通常每个套接字的地址只能使用一次”(端口号是我用netstat在CMD的DOS环境中看到的),出现这个异常应该是端口冲突,那么我应该怎么样在程序中动态绑定一个可以用的端口呢? --------------------编程问答-------------------- 调用socket的close的时候会引发异常。你要捕获一下异常然后进行处理。

你那些回调方法里的EndXXX方法都加上捕获异常,然后做出处理。不然你close时引发的异常它不知道如何处理,所以就退出程序了。

你出现异常后,Socket监听的端口没有释放,所以再运行就出现“通常每个套接字的地址只能使用一次”的异常了。 --------------------编程问答-------------------- LS说的差不多了
然后使用ShurtDown方法,从容关闭

LZ最好看下一些别人写的通信程序,你的还是比较乱的
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,