黑马程序员--多线程与套接字组合:简单聊天室(2)

------- Windows Phone 7手机开发.Net培训、期待与您交流! -------

本篇主要叙述如何发送消息以及对聊天室程序的总结.

在服务端启动服务后,客户端才可以向服务端建立连接。

客户端向服务端发送消息的:

1.建立连接.

2.发送消息.

        hread threadClient = null;//客户端负责接收服务端发来的数据的线程
        Socket socketClient = null;
        private void btnConnect_Click(object sender, EventArgs e)
        {
            IPAddress address = IPAddress.Parse(txtIP.Text.Trim());//获得IP
            IPEndPoint endpoint = new IPEndPoint(address, int.Parse(txtPort.Text.Trim()));
            //创建客户端连接套接字
             socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socketClient.Connect(endpoint);
            //创建线程,监听服务端发来的消息
            threadClient = new Thread(RecMsg);
            threadClient.IsBackground = true;
            threadClient.Start();
        }
        /// <summary>
        /// 接收服务端发来的消息.
        /// </summary>
        void RecMsg()
        {
            while (true)
            {
                // 定义一个接收用的缓存区(2M字节数组)
                byte[] arrMsgRec = new byte[1024 * 1024 * 2];
                //讲接收到的数据存入arrMsgRec数组,并返回真正接收到的数据的长度
                int length = -1;
                try
                {

                    length = socketClient.Receive(arrMsgRec);
                }
                catch (SocketException ex)//先捕捉最可能发生的异常
                {

                    SHowMsg("异常 " + ex.Message);
                    
                    break;
                }
                catch (Exception ex)//再捕捉一般的异常
                {
                    SHowMsg("异常 " + ex.Message);
                    break;
                }

                //此时,是将所有的元素都转化整数组
                string strMSG = System.Text.Encoding.UTF8.GetString(arrMsgRec,0,length);
                SHowMsg(strMSG);
            }
        }
向服务端发送数据:

  //向服务端发送数据
        private void btnSendToServer_Click(object sender, EventArgs e)
        {
            string msg=txtMsgToServer.Text;//要发送的文本.
            byte[] arrMsg = Encoding.UTF8.GetBytes(msg);//转换为字节
            byte[] arrMsgSend = new byte[arrMsg.Length + 1];//定义一个新的数组,设置数组的第一位为标识位,好判断发送的类型.
            arrMsgSend[0] = 0;//设置标识位,0代表是文字
            Buffer.BlockCopy(arrMsg, 0, arrMsgSend, 1, arrMsg.Length);
            
          socketClient.Send(arrMsgSend);
            SHowMsg(msg); 
        }

 #region 选择要发送的文件-------------void btnChooseFile_Click
        /// <summary>
        /// 选择要发送的文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnChooseFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();//打开对话框
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtFileName.Text = ofd.FileName;
                
            }
        } 
        #endregion
        //像服务端发送文件
        private void btnSendFileToServer_Click(object sender, EventArgs e)
        {
            //用文件流打开用户选择的  文件
            using (FileStream fs = new FileStream(txtFileName.Text,FileMode.Open))
            {
                byte[] arrFile = new byte[1024 * 1024 * 2];//定一个2M的数组
                //将文件数组督导  数组arrFile中,并获取读取的真实数据长度length
               int length= fs.Read(arrFile, 0,arrFile.Length);
               byte[] arrFileSend = new byte[length + 1];
               arrFileSend[0] = 1;//1代表发送的是文件
               //for (int i = 0; i < length; i++)
               //{
               //    arrFileSend[i + 1] = arrFile[i];
               //}
               Buffer.BlockCopy(arrFile, 0, arrFileSend, 1, length);
              // arrFile.CopyTo(arrFileSend, length);
                //发送了 包含了标识位的的数组文件
               socketClient.Send(arrFileSend);
            }
        }
    }

总结:

1.在客户端服务端用死循环来不断的侦听客户端和服务端发来的文件请求和消息.

2.要关闭TextBox的CheckForIllegalCrossThreadCalls 属性,以免产生跨线程调用的错误

TextBox.CheckForIllegalCrossThreadCalls = false;//关闭Text对错误线程的调用



------- Windows Phone 7手机开发.Net培训、期待与您交流! -------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值