黑马程序员_学习笔记之Socket_简单聊天程序

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

IPAddress类:包含了一个IP地址
IPEndPoint类:包含了一个IP地址和端口号
Socket方法:
  new Socket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType)  创建一个Socket对象
    AddressFamily 成员指定Socket用来解析地址的寻址方案,例如:InterNetwork表示使用使用一个IP版本4地址连接
  SocketType定义要打开的Socket类型
  ProtocolType枚举向Windows Sockets API通知所请求的协议 TCP、UDP等
  Bind() 绑定一个本地的IP和端口号,IPEndPoint
  Listen() 让Socket监听传入的连接尝试,并指定监听队列容量,可设置容量大小与系统,服务器配置有关
  Accept() 接受连接并返回一个新连接Socket
  Connect() 初始化与另一个Socket的连接
  Send() 输出数据到Socket
  Receive() 从Socket中接收数据
  Close() 关闭Socket(销毁连接) 

 

服务端代码

首先声明全局变量
  Socket socketWacth; // 声明负责监听套接字  因为要创建多线程,所在要声明为全局变量      
  Thread thAccept; // 声明负责接受客户端连接请求的线程
  Dictionary<string, Socket> socketConns = new Dictionary<string, Socket>(); // 声明负责与客户端通信的连接套接字集合,由accept()方法返回
  Dictionary<string, Thread> thReceives = new Dictionary<string, Thread>(); // 声明负责接收客户端发来的消息的线程键值对集合

创建监听socket
  //创建负责监听的套接字 AddressFamily指地址类型,协议族,用来解析地址的寻址方案,使用IPv4,流式连接Socket,TCP传输协议
  socketWacth = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  IPAddress address = IPAddress.Parse(txtIP.Text.Trim()); // 获取IP地址
  IPEndPoint endpoint = new IPEndPoint(address, int.Parse(txtPort.Text.Trim())); // 创建IP端点 包括IP地址及端口
  socketWacth.Bind(endpoint);  // 为监听套接字绑定IP端点
  socketWacth.Listen(10);  // 开始监听并设置监听队列为10 即最多只能同时监听10个客户端连接请求
  ShowMessage("服务器已启动,正在监听中…");

创建接受客户端连接请求线程,因为Accept()会卡住线程,直到成功接受才会结束,因此要单独创建一个线程
  thAccept = new Thread(Accept); // 创建接受客户端连接请求的线程
  thAccept.IsBackground = true; // 设置为后台线程
  thAccept.Start(); // 启动线程
  
      void Accept()  // 接受客户端连接请求线程所调用的方法
        {
            while (true) // 使其循环接受请求
            {
                Socket socketConn = socketWacth.Accept();  // 接受监听队列中的客户端连接请求,返回一个负责与客户端通信的连接套接字
                string endpoint = socketConn.RemoteEndPoint.ToString();  // 获取客户端的IP地址及端口
                listEndpoint.Items.Add(endpoint); // 像用户列表中添加一个用户IP端点(IP地址及端口),作为用户的唯一标识
                socketConns.Add(endpoint, socketConn); // 将与客户端通信的套接字对象添加到键值对集合中,并以客户端IP端点为键

      // 此处为创建接收客户端发来的消息的线程,Receive()方法也会卡住线程,也要新建线程,并且要为每个客户端都创建一个,所以使用集合
                Thread thReceive = new Thread(Receive);
                thReceive.IsBackground = true;
                thReceive.Start(socketConn);
                thReceives.Add(endpoint, thReceive);  // 添加到接收客户端发来的消息的线程键值对集合中  
            
                ShowMessage(endpoint + "连接成功");
            }
        }

    void Receive(object objConn)  // 接收客户端消息所使用的方法,带参数的线程委托必须使用object类型
        {
            while (true)
            {
                Socket socketConn = objConn as Socket;  // 转换为Socket类型,与当前发送消息的客户端连接的Socket
                byte[] arrMsg = new byte[1024 * 1024 * 2];  // 定义一个用来接收数据的缓存区,即一个2M的字节数组
                int msgLen = socketConn.Receive(arrMsg);  // 接受消息并存入到arrMsg字节数组中,返回消息的长度
                string strMsg = System.Text.Encoding.Default.GetString(arrMsg, 0, msgLen); //转换为字符串
                ShowMessage(socketConn.RemoteEndPoint.ToString()+"对你说:"+strMsg);
            }
        } 

 向客户端发送消息
  string strSend = txtSend.Text.Trim(); // 获取要发送的文本
  byte[] arrSend = System.Text.Encoding.Default.GetBytes(strSend);  // 转换为字节数组           
  socketConns[listEndpoint.SelectedItem.ToString()].Send(arrSend);  // 向所选择的用户发送数据        
  ShowMessage("你对" +listEndpoint.SelectedItem.ToString() + "说:" + strSend);

 

客户端代码

 声明一个全局变量
  Socket socketConn; // 用来储存与服务器连接的Socket 

创建连接Socket并连接  
  IPAddress addess = IPAddress.Parse(txtIP.Text.Trim());
  IPEndPoint endpoint = new IPEndPoint(addess,int.Parse(txtPort.Text.Trim()));  // 获取IP端点
  socketConn = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);  // 创建连接Socket
  socketConn.Connect(endpoint);  // 连接服务器
  ShowMessage("连接成功");      

接收服务端发来的消息  
  Thread thReceive = new Thread(Receive);  //创建一个线程来接收信息
  thReceive.IsBackground = true;
  thReceive.Start();

   void Receive()  // 接收消息的方法
        {
            while (true)
            {
                byte[] arrMsg = new byte[1024 * 1024 * 2];  // 定义一个用来接收数据的缓存区,即一个2M的字节数组
                int msgLen = socketConn.Receive(arrMsg);  // 接受服务端发来的消息
                string strMsg = System.Text.Encoding.Default.GetString(arrMsg,0,msgLen); // 转换为字符串
                ShowMessage("服务器对你说:"+strMsg);
            }
        }

向服务端发消息
  string strMsg = txtSend.Text.Trim();
  byte[] arrMsg = System.Text.Encoding.Default.GetBytes(strMsg);  // 转换为字节数组,以便用来与服务器进行传输
  socketConn.Send(arrMsg);
  ShowMessage("你对服务器说:" + strMsg);

  void ShowMessage(string msg)      //  向文本框添加信息
        {
            txtMsg.AppendText(msg + "\n");
        }

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

posted @ 2012-01-26 00:24 雨夜_ 阅读(296) 评论(1) 编辑 收藏

 回复 引用 查看   
#1楼2012-01-30 09:06 | 九五二七      
自己创建Thread使用还不如用异步方式