我想写个qq下线的功能,就是说一个人下线,用广播通知其他的人我下线了,我写完了上线的好使,但是下线的时候出现这个问题  以一种访问权限不允许的方式做了一个访问套接字的尝试。红色的代码就是错误的地方,问题一解决马上给分,每半天关注一下这个帖子。using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;namespace convey_file
{
    public partial class Form1 : Form
    {      
       private Socket sock1, sock2,sock3;
       UdpClient udp1, udp2;
       Thread th1,th2;
       bool I = true;
        public Form1()
        {
            InitializeComponent();
        }
        private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
        {        }
        private void Form1_Load(object sender, EventArgs e)
        {
            thread_start();            //开始接受广播
           udp_socket();              //发送自己的ip给广播内的用户
        }
        private void button1_Click(object sender, EventArgs e)
        {
            string filename = "";
            openFileDialog1.ShowDialog();
            filename = openFileDialog1.FileName;
            textBox1.Text = filename;
        }
        private void listener()
        {
            sock1 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            IPEndPoint iep1 = new IPEndPoint(IPAddress.Any,9050);
            EndPoint ep = (EndPoint)iep1;
            sock1.Bind(iep1);
            string[] word;
            Console.WriteLine("Ready to receive……");
            while (I)
            {
                byte[] data = new byte[1024];
                int rece = sock1.ReceiveFrom(data, ref ep);
                string infor = Encoding.Unicode.GetString(data, 0, rece);
                word = infor.Split('|');
               
                if (word[0] == "online")
                {
                    udp2 = new UdpClient(word[2],9000);
                    byte[] inf = Encoding.Unicode.GetBytes("online_ok|"+ Dns.GetHostName() + "|" + Dns.GetHostEntry(Dns.GetHostName()).AddressList[0]);
                    udp2.Send(inf,inf.Length);
                    dataGridView1.Rows.Add(word[2]);
                    udp2.Close();
                }
             //   MessageBox.Show(infor);
                
            }
            sock1.Close();         
        }
        private void listen()
        {
            udp1 = new UdpClient(9000);
            IPEndPoint iep = new IPEndPoint(IPAddress.Any,9000);
            while (I)
            {
                byte[] data = udp1.Receive(ref iep);
                if (data.Length > 0)
                {
                    string hua = Encoding.Unicode.GetString(data);                 //接收发送online后返回的信息
                    string[] hehe = hua.Split('|');                                    //接受
                    dataGridView1.Rows.Add(hehe[2]);
                }
            }
        }
        private void button2_Click_1(object sender, EventArgs e)
        {
        }
        private void button3_Click(object sender, EventArgs e)
        {
        }
        private void closing(object sender, FormClosingEventArgs e)
        {
            sock3 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            IPEndPoint remote = new IPEndPoint(IPAddress.Broadcast,11000);
            sock3.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
            byte[] info = Encoding.Unicode.GetBytes("close|" + Dns.GetHostName() + "|" + Dns.GetHostEntry(Dns.GetHostName()).AddressList[0]);
            sock3.SendTo(info, remote);
            sock3.Close();

            th1.Abort();
            th2.Abort();
            I = false;
           // sock2.Close();
            Application.Exit();
        }
        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)         //在textbox3中显示客户点击的ip
        {
            this.textBox3.Text = this.dataGridView1.CurrentRow.Cells[0].Value.ToString(); 
        }
        private void udp_socket()            //udp socket广播 接收数据包
        {
            sock2 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);       
            IPEndPoint iep2 = new IPEndPoint(IPAddress.Broadcast, 9050);                             //broadcast是提供ip广播地址
            sock2.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
            byte[] information = Encoding.Unicode.GetBytes("online|" + Dns.GetHostName() + "|" + Dns.GetHostEntry(Dns.GetHostName()).AddressList[0]);
            sock2.SendTo(information, iep2);  
            
        }
        private void thread_start()                     //from_load里调用的线程
        {
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
            th1 = new Thread(new ThreadStart(listener));
            th2 = new Thread(listen);
            th1.Start();
            th2.Start();
        }
        private void thread()
        {
           
        }
    }
}
 

解决方案 »

  1.   

    楼主的发送下线消息的代码不能放到closed事件中来,我觉得这个是错误的原因,我看了代码,应该没什么错。建议楼将相应操作放到线程中来处理,退出的时候,先开启线程广播下线消息,然后关闭窗体,等到线程广播完消息后,线程自然终止的时候程序就完全退出了。这样应该就不会有问题了。
      

  2.   

    要话在一个按钮中,用户单击下线,或在from closeing时,也触发按钮,
    在线程里做
      

  3.   

      private void listener() 
            { 
                sock1 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 
                IPEndPoint iep1 = new IPEndPoint(IPAddress.Any,9050); 
                EndPoint ep = (EndPoint)iep1; 
                sock1.Bind(iep1); 
                string[] word; 
                Console.WriteLine("Ready to receive……"); <------------- 怎么回事?