用Socket编写的聊天小程序

Socket是什么?

是套接字,除此之外我也不太清楚,先略过

 

直接上实例,首先服务端:

 private int ServerPoint = 8102;  //自定义端口号
 private string ServerUser = "Tracy"; //自定义昵称
 private Socket clientSK;
 private delegate void AppendRich(string txt,string user); //定义委托是为了避免在AppendText时出现"richTextBox1不是该线程创建"的错误提示

 private void Form1_Load(object sender, EventArgs e)
 {
            Thread listenThread = new Thread(new ThreadStart(AppInit));
            listenThread.Start(); //用多线程是为了防止sk.Listen(10)一直处于监听状态,导致UI界面卡死
 }
 private void AppInit()
 {
            Socket sk = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            EndPoint endPoint = new IPEndPoint(IPAddress.Any, ServerPoint);
            sk.Bind(endPoint); //实例化Socket并绑定端口
            sk.Listen(10); //开始监听,如果没有客户端连接将一直卡在这

            clientSK = sk.Accept(); //客户端连接,把这个有效的Socket连接赋给全局变量clientSK,程序继续走
            SendMsg("已成功连接到服务器", "系统消息");

            AppendRich dele = new AppendRich(AppendToRich); //实例化一个委托

            while (true) //用死循环保持一直通话
            {
                try
                {
                    byte[] receiveBT = new byte[1024];
                    int receiveInt = clientSK.Receive(receiveBT); //获取接收的消息
                    if (receiveInt == 0) //如果接收到空消息,跳出循环
                    {
                        break;
                    }
                    string receiveStr = Encoding.UTF8.GetString(receiveBT, 0, receiveInt); //接收的消息转为string
                    richTextBox1.Invoke(dele, new object[] { receiveStr.Substring(9), receiveStr.Substring(0, 9).Trim() }); //添加到richbox中,这里我自定义了string的格式,分昵称和消息内容
                }
                catch (Exception ex)
                {
                    break;
                }
            }
            //此时跳出了循环,意味着程序即将关闭
            clientSK.Close();  //关闭连接到客户端的Socket
            sk.Close();  //关闭实例化的Socket
            richTextBox1.Invoke(dele, new object[] { "连接已终止", "系统消息" }); //利用委托向RichTextBox1中添加String
 }
 private void SendMsg(string txt, string user)
 {
            string nickName = user;
            string sendStr = nickName.PadLeft(9) + txt;
            byte[] bs = Encoding.UTF8.GetBytes(sendStr);
            clientSK.Send(bs, bs.Length, 0);//向客户端发送信息
 }
 private void AppendToRich(string txt,string user)
 {
            if (txt == string.Empty)
            {
                return;
            }
            if (user == ServerUser)  //判断用户,以便区分颜色和字体
            {
                richTextBox1.SelectionFont = new Font(new FontFamily("宋体"), 9);
                richTextBox1.SelectionColor = Color.Green;
            }
            else
            {
                richTextBox1.SelectionFont = new Font(new FontFamily("宋体"), 9);
                richTextBox1.SelectionColor = Color.Blue;
            }
            richTextBox1.AppendText("\r\n" + user + " " + DateTime.Now.ToString("HH:mm:ss") + "\r\n");

            if (user == ServerUser)
            {
                richTextBox1.SelectionFont = new Font(new FontFamily("楷体"), 12);
                richTextBox1.SelectionColor = Color.FromArgb(0, 155, 255);
            }
            else
            {
                richTextBox1.SelectionFont = new Font(new FontFamily("宋体"), 9);
                richTextBox1.SelectionColor = Color.Black;
            }
            richTextBox1.AppendText(txt);
            richTextBox1.ScrollToCaret();//滚动条保持最底部
            textBox2.ResetText();
            textBox2.Focus();
 }
ServerCode

 

 

 

 

客户端:

 private int ServerPoint = 8102;  //自定义端口号,要与之前服务端一致
 private string ClientUser = "诺克萨斯", ClientIP = "127.0.0.1"; //自定义昵称,以及服务端IP
 private Socket newclient;
 private delegate void AppendRich(string txt, string user);

 private void Form1_Load(object sender, EventArgs e)
 {
            Thread listenThread = new Thread(new ThreadStart(AppInit));
            listenThread.Start();
 }

 private void AppInit()
 {

            newclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint ie = new IPEndPoint(IPAddress.Parse(ClientIP), ServerPoint); // 服务器的IP和端口
            newclient.Connect(ie); //这里不需要绑定,直接连接到服务端
            string hostName= Dns.GetHostName(); //获取客户端主机名
            IPHostEntry iphostentry = Dns.GetHostEntry(hostName);
            List<IPAddress> ips=iphostentry.AddressList.ToList(); //获取客户端IP

            SendMsg(ips[2].ToString() + " 已连接", "系统消息");
            AppendRich dele = new AppendRich(AppendToRich);

            while (true)
            {
                try
                {
                    byte[] receiveBT = new byte[1024];
                    int receiveInt = newclient.Receive(receiveBT); //获取接收的消息
                    if (receiveInt == 0)
                    {
                        break;
                    }
                    string receiveStr = Encoding.UTF8.GetString(receiveBT, 0, receiveInt); //接收的消息转为string
                    richTextBox1.Invoke(dele, new object[] { receiveStr.Substring(9), receiveStr.Substring(0, 9).Trim() }); //添加到richbox中
                }
                catch(Exception ex)
                {
                    break;
                }
            }
            newclient.Close();
            richTextBox1.Invoke(dele, new object[] { "连接已终止", "系统消息" });
 }
 private void SendMsg(string txt, string user)
 {
            string nickName = user;
            string sendStr = nickName.PadLeft(9) + txt;
            byte[] bs = Encoding.UTF8.GetBytes(sendStr);
            newclient.Send(bs, bs.Length, 0);//发送信息
 }
 private void AppendToRich(string txt, string user)
 {
            if (txt == string.Empty)
            {
                return;
            }
            richTextBox1.AppendText("\r\n" + user + " " + DateTime.Now.ToString("HH:mm:ss") + "\r\n" + txt);
            richTextBox1.ScrollToCaret();//滚动条保持最底部
            textBox1.ResetText();
            textBox1.Focus();
 }
ClientCode

 

posted on 2014-12-03 11:52  邓绍俊  阅读(316)  评论(0编辑  收藏  举报

导航