} // W_GroupTalk /// <summary> /// 窗口载入时 /// </summary> /// <param name="sender">the sender</param> /// <param name="e">the e</param> private void GroupTalk_Load(object sender, EventArgs e) { appendString = new DelegateMem.AppendDelegate(DelegateMethod.appendMethod); // 开始遍历消息列表 pollMsgTask = Task.Factory.StartNew(() => pollMsg(cancellationTokenSource.Token), cancellationTokenSource.Token); } // GroupTalk_Load
} // recCallBack /// <summary> /// 回调函数发:送数据 /// </summary> /// <param name="ar">the ar</param> public static void sendCallBack(IAsyncResult ar) { // 当前用户实例 User currentUser = User.GetInstance(); SendCallBackParam sendCallBackParam = (SendCallBackParam)ar.AsyncState; ListBox lstBox_recMsg = sendCallBackParam.lstBox_recMsg; string strSend = sendCallBackParam.strSend; DelegateMem.AppendDelegate appendString = sendCallBackParam.appendString; try { //异步通信 结束数据的异步发送 currentUser.socket.EndSend(ar); strSend = "发:" + strSend; // 在右侧显示 string showStr = strSend.PadLeft(lstBox_recMsg.Width / 10, ' '); lstBox_recMsg.Invoke(appendString, lstBox_recMsg, showStr); } // try catch (System.Exception ex) { SocketHandler.ShutDownConn(currentUser.socket); lstBox_recMsg.Invoke(appendString, lstBox_recMsg, "服务器断开了TCP连接"); } // catch } // sendCallBack
} // W_SingleChat /// <summary> /// 窗口载入之时 /// </summary> /// <param name="sender">the sender</param> /// <param name="e">the e</param> private void W_SingleChat_Load(object sender, EventArgs e) { appendString = new DelegateMem.AppendDelegate(DelegateMethod.appendMethod); // 从MsgList中轮询数据 pollMsgTask = Task.Factory.StartNew(() => pollMsg(cancellationTokenSource.Token), cancellationTokenSource.Token); } // W_SingleChat_Load
/// <summary> /// Initializes RecvCallBackParam /// </summary> /// <param name="lstBox_statu">a listbox that show information</param> /// <param name="frd">a online user</param> /// <param name="appendString">append string to listbox</param> /// <param name="IsStart">whether start listening</param> public RecvCallBackParam(ListBox lstBox_statu, MyFriend frd, DelegateMem.AppendDelegate appendString, bool IsStart) { this.lstBox_statu = lstBox_statu; this.frd = frd; this.appendString = appendString; this.IsStart = IsStart; } // RecvCallBackParam
} // W_Login /// <summary> /// 单击登录按钮 /// </summary> /// <param name="sender">the sender</param> /// <param name="e">the e</param> private void btn_logIn_Click(object sender, EventArgs e) { // 定义添加文本的委托变量 DelegateMem.AppendDelegate appendString = new DelegateMem.AppendDelegate(DelegateMethod.appendMethod); // 获取当前用户的实例 User currentUser = User.GetInstance(); // 定义网络服务的一个实例 IMSLogStateChangeClient logIM = new IMSLogStateChangeClient(); string loginResault = logIM.changeLogState(txt_userName.Text, txt_userPwd.Text, false); if (loginResault == "1") { currentUser.userName = txt_userName.Text; #region 连接到服务器并接收消息 if (currentUser.socket == null) { currentUser.socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); } // if if (!currentUser.socket.Connected) { // 获得一个可用的IPV4地址 IPEndPoint remoteep = IPEndPointHandler.GetIPEndPoint(); AsyncCallback callBack = new AsyncCallback(CallBackFunc.connCallBack); currentUser.socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); currentUser.socket.BeginConnect(remoteep, callBack, currentUser); Thread.Sleep(1000); // Islogin 在 connCallBack中修改 if (currentUser.Islogin == true) { MessageBox.Show("登录成功"); this.DialogResult = DialogResult.OK; } // if } // if #endregion } // if else if (loginResault == "0") { MessageBox.Show("已有账号登录");//在另一个客户端尝试登录的时候执行的到。 } // else if else { MessageBox.Show("用户名或密码错误"); } // else } // btn_logIn_Click
/// <summary> /// 开始监听 /// </summary> /// <param name="ar"></param> public static void acceptCallBack(IAsyncResult ar) { // 初始化需要用的委托 Friends friends = Friends.GetInstance(); DelegateMem.AppendDelegate appendString; appendString = new DelegateMem.AppendDelegate(DelegateMethod.appendMethod); try { // 初始化关键参数 AcceptCallBackParam acceptCallBackParam = (AcceptCallBackParam)ar.AsyncState; TcpListener listener = acceptCallBackParam.listener; bool IsStart = acceptCallBackParam.IsStart; ListBox lstBox_statu = acceptCallBackParam.lstBox_statu; try { //完成异步接受连接请求的异步调用 //将连接信息添加到列表和下拉列表 Socket clientSocket = listener.EndAcceptSocket(ar); MyFriend frd = new MyFriend(clientSocket); // 加入好友 lock (friends.friendList) { friends.friendList.Add(frd); } string connMsg = clientSocket.RemoteEndPoint.ToString() + "已连接..."; lstBox_statu.Invoke(appendString, connMsg, lstBox_statu); AsyncCallback callBack; if (IsStart) { callBack = new AsyncCallback(acceptCallBack); listener.BeginAcceptSocket(callBack, acceptCallBackParam); } // if //开始在连接上进行异步的数据接收 frd.clearBuffer(); // 初始化要传入的参数 RecvCallBackParam recvCallBackParam = new RecvCallBackParam( lstBox_statu, frd, appendString, IsStart ); callBack = new AsyncCallback(CallBackFunc.recvCallBack); frd.socket.BeginReceive(frd.recvBuffer, 0, frd.recvBuffer.Length, SocketFlags.None, callBack, recvCallBackParam); } // try catch (System.Exception ex) { IsStart = false; acceptCallBackParam.IsStart = false; } // catch } // try catch (System.Exception ex) { // 终于封装了这个异常!! 即调用stop只会关闭监听,但是仍然会执行这个函数,前面会转型失败.....跳转到这 } // catch } // acceptCallBack
} // acceptCallBack /// <summary> /// 接受消息 /// </summary> /// <param name="ar"></param> public static void recvCallBack(IAsyncResult ar) { try { // 初始化关键参数 RecvCallBackParam recvCallBackParam = (RecvCallBackParam)ar.AsyncState; ListBox lstBox_statu = recvCallBackParam.lstBox_statu; MyFriend frd = recvCallBackParam.frd; DelegateMem.AppendDelegate appendString = recvCallBackParam.appendString; bool IsStart = recvCallBackParam.IsStart; Friends friends = Friends.GetInstance(); try { int i = frd.socket.EndReceive(ar); if (i == 0) { lock (friends) { friends.friendList.Remove(frd); } frd.Dispose(); return; } // if else { string strData = Encoding.UTF8.GetString(frd.recvBuffer, 0, i); // 解析收到的数据 C2CAnayMsg c2cAnayMsg = new C2CAnayMsg(strData); #region 登录 if (c2cAnayMsg.type == "login") { frd.userName = c2cAnayMsg.srcUser; } // if-login #endregion #region 群聊 if (c2cAnayMsg.type == "group") { string finalData = string.Format("收到来自:{0},发送给:{1} 的消息: {2}", c2cAnayMsg.srcUser, c2cAnayMsg.destName, c2cAnayMsg.content); lstBox_statu.Invoke(appendString, finalData, lstBox_statu); foreach (MyFriend destFrd in friends.friendList) { if (destFrd.userName != c2cAnayMsg.srcUser) { string groupMsg = BuildMsg.buildSendMsg("group", c2cAnayMsg.srcUser, c2cAnayMsg.srcIP, c2cAnayMsg.destName, c2cAnayMsg.content); sendData(destFrd, groupMsg); } } } #endregion #region 点对点聊天 if (c2cAnayMsg.type == "client2client") { string finalData = string.Format("收到来自:{0},发送给:{1} 的消息: {2}", c2cAnayMsg.srcUser, c2cAnayMsg.destName, c2cAnayMsg.content); lstBox_statu.Invoke(appendString, finalData, lstBox_statu); // 寻找目的frd int destUserIndex = 0; for (destUserIndex = 0; destUserIndex < friends.friendList.Count; destUserIndex++) { MyFriend destFrd = (MyFriend)friends.friendList[destUserIndex]; if (destFrd.userName == c2cAnayMsg.destName) { break; } } // for if (destUserIndex == friends.friendList.Count) { // TODO 通知发送方,对方不在线 int srcUserIndex = 0; for (srcUserIndex = 0; srcUserIndex < friends.friendList.Count; srcUserIndex++) { MyFriend destFrd = (MyFriend)friends.friendList[srcUserIndex]; if (destFrd.userName == c2cAnayMsg.srcUser) { break; } } // for // 这种情况,客户端收到后,srcUser是自己的名字,而destName不是自己的名字 string offlineMsg = BuildMsg.buildSendMsg("offline", c2cAnayMsg.srcUser, c2cAnayMsg.srcIP, c2cAnayMsg.destName, "对方未在线"); sendData((MyFriend)friends.friendList[srcUserIndex], offlineMsg); } // if else { // 转发出去 这种情况,转发给另外一个用户,src是发送者的名字,destName是自己的名字 string onlineMsg = BuildMsg.buildSendMsg("client2client", c2cAnayMsg.srcUser, c2cAnayMsg.srcIP, c2cAnayMsg.destName, c2cAnayMsg.content); sendData((MyFriend)friends.friendList[destUserIndex], onlineMsg); } // else } // if-lient2client #endregion #region 退出 if (c2cAnayMsg.type == "logout") { // TDO 已处理 string quitMsg = frd.userName + "(" + frd.socket.LocalEndPoint + ")断开了连接"; lstBox_statu.Invoke(appendString, quitMsg, lstBox_statu); lock (friends) { friends.friendList.Remove(frd); } frd.Dispose(); } // if #endregion #region 添加好友 if (c2cAnayMsg.type == "addfrd") { int destUserIndex = 0; for (destUserIndex = 0; destUserIndex < friends.friendList.Count; destUserIndex++) { MyFriend destFrd = (MyFriend)friends.friendList[destUserIndex]; if (destFrd.userName == c2cAnayMsg.destName) { break; } // if } // for // 被添加的用户肯定存在 string onlineMsg = BuildMsg.buildSendMsg("addfrd", c2cAnayMsg.srcUser, c2cAnayMsg.srcIP, c2cAnayMsg.destName, c2cAnayMsg.content); sendData((MyFriend)friends.friendList[destUserIndex], onlineMsg); } #endregion frd.clearBuffer(); AsyncCallback callBack = new AsyncCallback(recvCallBack); frd.socket.BeginReceive(frd.recvBuffer, 0, frd.recvBuffer.Length, SocketFlags.None, callBack, recvCallBackParam); } // else } // try catch (System.Exception ex) { lock (friends) { friends.friendList.Remove(frd); } frd.Dispose(); } // catch } // try catch (System.Exception ex) { } // cath } // recvCallBack
/// <summary> /// Initializes SendCallBackParam /// </summary> /// <param name="strSend">message that will be send</param> /// <param name="lstBox_recMsg">chat window's listbox that show what be sended</param> /// <param name="appendString">a delegate member to append string</param> public SendCallBackParam(string strSend, ListBox lstBox_recMsg, DelegateMem.AppendDelegate appendString) { this.strSend = strSend; this.lstBox_recMsg = lstBox_recMsg; this.appendString = appendString; } // SendCallBackParam
} // W_Main /// <summary> /// 载入窗体 /// </summary> /// <param name="sender">the sender</param> /// <param name="e">the e</param> private void W_Main_Load(object sender, EventArgs e) { //实例化委托对象,绑定方法 appendString = new DelegateMem.AppendDelegate(DelegateMethod.appendMethod); } // W_Main_Load