namespace MyChatServer
{
    public partial class MyChatServer : Form
    {
        IPAddress myip;
        IPEndPoint myserver;
        Socket mysocket;
        Socket handler;
        private stateobject state;
        bool closes = false;
        static ManualResetEvent myreset = new ManualResetEvent(false);
        delegate void apptext(string m);
        public MyChatServer()
        {
            InitializeComponent();
        }        private void Form1_Load(object sender, EventArgs e)
        {
            String conn = "Data Source=.;Initial Catalog=chat;Integrated Security=True";
            string strSQL = " select * from users ";
            SqlConnection con = new SqlConnection(conn);
            con.Open();
            SqlCommand com = con.CreateCommand();
            com.CommandText = strSQL;
            SqlDataAdapter da = new SqlDataAdapter(com);
            DataSet ds = new DataSet();
            da.Fill(ds);
            try
            {
                if (ds.Tables[0].Rows.Count > 1)
                {
                    //将获得数据源赋予数据库控件
                    dataGridView1.DataSource = ds.Tables[0];
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
            finally
            {
                da.Dispose();
                con.Dispose();
                con.Close();
            }
            string HostName = Dns.GetHostName(); //得到主机名
            IPHostEntry IpEntry = Dns.GetHostEntry(HostName); //得到主机IP
            string strIPAddr = IpEntry.AddressList[1].ToString(); 
            foreach (System.Net.IPAddress ip in IpEntry.AddressList)
            {
            this.servername.Text = strIPAddr;
            }
        }
        private void starts_Click(object sender, EventArgs e)
        { 
            try
            {
               myip = IPAddress.Parse(servername.Text);
            }
            catch (Exception s)
            { 
                 MessageBox.Show(s.Message);
            }
            try
            {
                myserver = new IPEndPoint(myip, Int32.Parse(serverport.Text));
                mysocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                mysocket.Bind(myserver);
                int no = Int32.Parse(textBox1.Text);
                mysocket.Listen(no);
                serverstate.AppendText("服务器:" + servername.Text + "\r\n端口:" + serverport.Text + "开始监听...\r\n");
                Thread s;
                s = new Thread(new ThreadStart(target));
                s.Start();
                serverport.ReadOnly = true;
                servername.ReadOnly = true;
                starts.Enabled = false;
                textBox1.Enabled = false;
            }
            catch (Exception p)
            {
                MessageBox.Show(p.Message);
            }        }
        private void target()
        {
            Thread.CurrentThread.IsBackground = true;
            while (true)
            {
                if (closes == true)
                    return;
                    myreset.Reset();
                    mysocket.BeginAccept(new AsyncCallback(acceptcall), mysocket);
                    myreset.WaitOne();
            }
        }
        private void apptextcall(string m)
        {
            this.serverstate.AppendText(m + "\r\n");
        }
        private void acceptcall(IAsyncResult ar)
        {
            Thread.CurrentThread.IsBackground=true;
            if (closes == true)
                return;
                myreset.Set();
                Socket p = (Socket)ar.AsyncState;
                handler = p.EndAccept(ar);
                state = new stateobject();
                state.worksoc = handler;
                string me = "客户端:" + handler.RemoteEndPoint.ToString() + "连接成功";
                handler.BeginReceive(state.mess, 0, 1000,0, new AsyncCallback(ReceiveData), state);
                if (this.serverstate.InvokeRequired)
                {
                    apptext settext = new apptext(apptextcall);
                   
                    this.Invoke(settext, new object[] { me });
                }
                else
                {
                    this.serverstate.AppendText(me + "\r\n");
                }
        }
        private void SendData(string data)
        {
            byte[] byteData = Encoding.Unicode.GetBytes(data);
            state.worksoc.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), state);
        }
        private void SendCallback(IAsyncResult ar)
        {
            try
            {
                Socket handler = (Socket)ar.AsyncState;
                int bytesSent = handler.EndSend(ar);
                
            }
            catch (Exception s)
            {
                MessageBox.Show(s.Message);            }
        }
               
        private void stops_Click(object sender, EventArgs e)
        {            
            try
            {                
                if (mysocket != null)
                {
                    DialogResult s = MessageBox.Show("退出可能会丢失客户端连接\r\n是否继续?", "警告", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
                    if (s == DialogResult.No)
                        return;
                    mysocket.Close();
                }
                closes =true;
                this.Close();
            }
            catch (Exception p)
            {
                MessageBox.Show(p.Message);
            }
        }
        private void ReceiveData(IAsyncResult ar)
        {
            stateobject state = (stateobject)ar.AsyncState;
            Socket handler = state.worksoc;
            int bytesRead = handler.EndSend(ar);
            /*这里需要判断 用户发送来的信息是哪一类的。
            * 比如当bytesRead=1的时候表示:客户端上用户点击了登录,发送的是用户名和密码,此刻要执行查询数据库,返回验证结果。
              如果当bytesRead=2时表示:客户端上用户点击注册,发送了个人的相关信息,服务器要将这些数据添加到数据库,返回注册结果。
            * bytesRead=4 ......等等 
            * 在这里应该怎么写?而且clientSocket.EndReceive(ar)最终接收的应该是一组数据信息,它应该把这些信息分开。这里有点晕...  还有那些处理方法写在不同的函数体里调用, 还是把整个放在一个类里?
            * 
            */
            handler.BeginReceive(state.mess, 0, 1000, 0, new AsyncCallback(ReceiveData), state);
        }
        private void MyChatServer_MinimumSizeChanged(object sender, EventArgs e)
        {
            this.Hide();
        }        private void notifyIcon1_Click(object sender, EventArgs e)
        {
            this.Show();
        }        private void MyChatServer_Deactivate(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.Hide();
            }
        }        private void serverstate_TextChanged(object sender, EventArgs e)
        {        }        }
    }
    
    public class stateobject
    {
        public Socket worksoc;
        public StringBuilder sb=new StringBuilder();
        public int length = 1024;
        public byte[] mess;
        public stateobject()
        { mess = new byte[length]; }
    }另外我规定的消息格式是TLV形式  主要就是怎么分开接收不会求指教~~~

解决方案 »

  1.   

    T   T
     private void ReceiveData(IAsyncResult ar)
            {
                stateobject state = (stateobject)ar.AsyncState;
                Socket handler = state.worksoc;
                int bytesRead = handler.EndSend(ar);
                /*这里需要判断 用户发送来的信息是哪一类的。
                * 比如当bytesRead=1的时候表示:客户端上用户点击了登录,发送的是用户名和密码,此刻要执行查询数据库,返回验证结果。
                  如果当bytesRead=2时表示:客户端上用户点击注册,发送了个人的相关信息,服务器要将这些数据添加到数据库,返回注册结果。
                * bytesRead=4 ......等等 
                * 在这里应该怎么写?而且clientSocket.EndReceive(ar)最终接收的应该是一组数据信息,它应该把这些信息分开。这里有点晕...  还有那些处理方法写在不同的函数体里调用, 还是把整个放在一个类里?
                * 
                */
                handler.BeginReceive(state.mess, 0, 1000, 0, new AsyncCallback(ReceiveData), state);
            }
      

  2.   

    private void ReceiveData(IAsyncResult ar)
            {
                
                stateobject state = (stateobject)ar.AsyncState;
                
                Socket handler = state.worksoc;
                /*这里需要判断 用户发送来的信息是哪一类的。
                * 比如当bytesRead=1的时候表示:客户端上用户点击了登录,发送的是用户名和密码,此刻要执行查询数据库,返回验证结果。
                  如果当bytesRead=2时表示:客户端上用户点击注册,发送了个人的相关信息,服务器要将这些数据添加到数据库,返回注册结果。
                * bytesRead=4 ......等等 
                * 在这里应该怎么写?而且clientSocket.EndReceive(ar)最终接收的应该是一组数据信息,它应该把这些信息分开。这里有点晕...  还有那些处理方法写在不同的函数体里调用, 还是把整个放在一个类里?
                * 
                */
                string msg = Encoding.UTF8.GetString(state.mess, 0, state.length);
                if (this.richTextBox1.InvokeRequired) { this.Invoke(null, null); }
                else { this.richTextBox1.AppendText(msg+"\r\n"); }
                handler.BeginReceive(state.mess, 0, 1000, 0, new AsyncCallback(ReceiveData), state);
            }请问以上代码是否有错??接收的话怎么写有没人??