ChatClient.cs 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Net.Sockets;
  7. using System.Threading;
  8. using System.Windows.Forms;
  9. using Newtonsoft.Json;
  10. using SocketChat.Common;
  11. namespace SocketChat.Client
  12. {
  13. public partial class ChatClient : Form
  14. {
  15. #region 用户定义
  16. private Socket _clientSocket;
  17. private User _user;
  18. private bool linkFlag = false; //对话状态
  19. private bool uw = false; //写入对话内容
  20. private string getMess; //从服务端接受的数据
  21. private bool isExit = false; //连接状态 是否退出
  22. private TcpClient client; //客户端
  23. private NetworkStream networkStream; //传输流
  24. private BinaryReader br; //读传输流
  25. private BinaryWriter bw; //写传输流
  26. private delegate void AddListBoxItemCallBack(string str);
  27. private AddListBoxItemCallBack _addList;
  28. private delegate void AppendChatMsgTextCallBack(string str);
  29. private AppendChatMsgTextCallBack _appendChatMsgText;
  30. private delegate void AppendTcpInfoCallBack(string str);
  31. private AppendTcpInfoCallBack _appendTcpInfo;
  32. //在线人数
  33. private List<OnlineUser> _onlineUser = new List<OnlineUser>();
  34. #endregion 用户定义
  35. #region 系统函数
  36. public ChatClient()
  37. {
  38. InitializeComponent();
  39. }
  40. public ChatClient(User v_user)
  41. {
  42. InitializeComponent();
  43. this._user = v_user;
  44. //建立网络通信
  45. try
  46. {
  47. this.client = new TcpClient(this._user.p_serverIP, int.Parse(this._user.p_serverPort));//定义服务器端ip地址和端口,与服务器端定义要一致
  48. this.linkFlag = true;
  49. }
  50. catch
  51. {
  52. return;
  53. }
  54. this._addList = new AddListBoxItemCallBack(this.AddListBoxItem);
  55. this._appendChatMsgText = new AppendChatMsgTextCallBack(this.AppendChatMsgText);
  56. if (this.linkFlag)
  57. {
  58. //获取网络流
  59. networkStream = client.GetStream();
  60. //将网络作为二进制读写对象,使用utf8编码
  61. br = new BinaryReader(networkStream);
  62. bw = new BinaryWriter(networkStream);
  63. //发送套接字、编辑的内容、用户名、发送时间。
  64. ClientMsgModel msg = new ClientMsgModel()
  65. {
  66. IP = this._user.p_serverIP,
  67. Port = this._user.p_serverPort,
  68. Msg = this.txtSendMsg.Text,
  69. NowDate = DateTime.Now.ToString(),
  70. Type = "1",
  71. UserName = this._user.p_userName
  72. };
  73. //string sendMsg = ConvertJson.ToJson(msg);
  74. string sendMsg = JsonConvert.SerializeObject(msg);
  75. SendString(sendMsg);
  76. ThreadStart ts = new ThreadStart(ReceiveData);
  77. Thread thRece = new Thread(ts);
  78. thRece.Start();
  79. }
  80. this.Text = this.Text + " 当前登录名:" + this._user.p_userName;
  81. }
  82. #endregion 系统函数
  83. #region 用户函数
  84. private void ReceiveData()
  85. {
  86. while (this.isExit == false)
  87. {
  88. string receiveString = null;
  89. try
  90. {
  91. //从网络流中读出字符串
  92. //此方法会自动判断字符串长度前缀,并根据长度前缀读出字符串
  93. receiveString = br.ReadString();
  94. }
  95. catch
  96. {
  97. //底层套接字不存在时会出现异常
  98. //提示数据接收失败
  99. //TcpInfo.AppendText("接收数据失败");
  100. this.AppendTcpInfo("接收数据失败");
  101. }
  102. if (receiveString == null)
  103. {
  104. if (isExit == false)
  105. {
  106. MessageBox.Show("与服务器失去联系!");
  107. }
  108. break;
  109. }
  110. uw = true;
  111. getMess = receiveString;
  112. //提示接收到的数据
  113. //TcpInfo.AppendText(Environment.NewLine + "接收服务器数据:" + Environment.NewLine + receiveString);
  114. ServerMsgModel __serverMsg = (ServerMsgModel)JsonConvert.DeserializeObject(receiveString, typeof(ServerMsgModel));
  115. switch (__serverMsg.SendType)
  116. {
  117. case "1":
  118. this._onlineUser = __serverMsg.OnlineUser;
  119. for (int i = 0; i < __serverMsg.OnlineUser.Count; i++)
  120. {
  121. this.AddListBoxItem(__serverMsg.OnlineUser[i].UserName);
  122. }
  123. break;
  124. case "2":
  125. this.AppendChatMsgText(__serverMsg.SendMsg);
  126. break;
  127. default: break;
  128. }
  129. }
  130. }
  131. private void SendString(string str)
  132. {
  133. try
  134. {
  135. //将字符串写入网络,此方法会自动附加字符串长度前缀
  136. bw.Write(str);
  137. bw.Flush();
  138. //提示发送成功
  139. TcpInfo.AppendText("发送:" + str);
  140. }
  141. catch
  142. {
  143. //提示发送失败
  144. TcpInfo.AppendText("发送失败!");
  145. }
  146. }
  147. public void AddListBoxItem(string str)
  148. {
  149. if (this.lbx_online.InvokeRequired)
  150. {
  151. if (this._addList != null)
  152. {
  153. this.Invoke(_addList, str);
  154. }
  155. }
  156. else
  157. {
  158. if (!this.lbx_online.Items.Contains(str))
  159. {
  160. this.lbx_online.Items.Add(str);
  161. }
  162. }
  163. }
  164. public void AppendChatMsgText(string str)
  165. {
  166. if (this.txtChatMsg.InvokeRequired)
  167. {
  168. if (this._appendChatMsgText != null)
  169. {
  170. this.txtChatMsg.Invoke(this._appendChatMsgText, str);
  171. }
  172. }
  173. else
  174. {
  175. this.txtChatMsg.AppendText(str + Environment.NewLine);
  176. }
  177. }
  178. public void AppendTcpInfo(string str)
  179. {
  180. if (this.TcpInfo.InvokeRequired)
  181. {
  182. if (this._appendTcpInfo != null)
  183. {
  184. this.TcpInfo.Invoke(this._appendTcpInfo, str);
  185. }
  186. }
  187. else
  188. {
  189. this.TcpInfo.AppendText(str);
  190. }
  191. }
  192. #endregion 用户函数
  193. #region 窗体事件
  194. private void btnSend_Click(object sender, EventArgs e)
  195. {
  196. try
  197. {
  198. //Func<OnlineUser, bool> b =
  199. OnlineUser ol = this._onlineUser.Where(delegate (OnlineUser olUser)
  200. {
  201. return olUser.UserName == this.lbx_online.SelectedItem.ToString();
  202. }).FirstOrDefault();
  203. //发送套接字、编辑的内容、用户名、发送时间。
  204. ClientMsgModel msg = new ClientMsgModel()
  205. {
  206. IP = this._user.p_serverIP,
  207. Port = this._user.p_serverPort,
  208. Msg = this.txtSendMsg.Text,
  209. NowDate = DateTime.Now.ToString(),
  210. Type = "2",
  211. UserName = this._user.p_userName,
  212. ReceiveIP = ol.IP,
  213. ReceivePort = ol.Port,
  214. };
  215. //string sendMsg = ConvertJson.ToJson(msg);
  216. string sendMsg = JsonConvert.SerializeObject(msg);
  217. SendString(sendMsg);
  218. this.txtSendMsg.Clear();
  219. }
  220. catch (Exception ex)
  221. {
  222. throw ex;
  223. }
  224. }
  225. private void btnClose_Click(object sender, EventArgs e)
  226. {
  227. try
  228. {
  229. this.Close();
  230. }
  231. catch (Exception ex)
  232. {
  233. throw ex;
  234. }
  235. }
  236. private void ChatClient_FormClosing(object sender, FormClosingEventArgs e)
  237. {
  238. try
  239. {
  240. if (this.client != null)
  241. {
  242. //发送套接字、编辑的内容、用户名、发送时间。
  243. ClientMsgModel msg = new ClientMsgModel()
  244. {
  245. IP = this._user.p_serverIP,
  246. Port = this._user.p_serverPort,
  247. Msg = "SignOut",
  248. NowDate = DateTime.Now.ToString(),
  249. Type = "3",
  250. UserName = this._user.p_userName
  251. };
  252. //string sendMsg = ConvertJson.ToJson(msg);
  253. string sendMsg = JsonConvert.SerializeObject(msg);
  254. isExit = true;
  255. br.Close();
  256. bw.Close();
  257. this.client.Close();
  258. }
  259. }
  260. catch (Exception ex)
  261. {
  262. throw ex;
  263. }
  264. }
  265. #endregion 窗体事件
  266. }
  267. }