frmServer.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using System.Runtime.InteropServices;
  10. using HPSocketCS;
  11. namespace SSLPackServerNS
  12. {
  13. public enum AppState
  14. {
  15. Starting, Started, Stoping, Stoped, Error
  16. }
  17. public partial class frmServer : Form
  18. {
  19. private AppState appState = AppState.Stoped;
  20. private delegate void ShowMsg(string msg);
  21. private ShowMsg AddMsgDelegate;
  22. // 两种构造方式,第一种
  23. //HPSocketCS.SSLPackServer server = null;
  24. // 两种构造方式,第二种
  25. HPSocketCS.SSLPackServer server = new HPSocketCS.SSLPackServer(SSLVerifyMode.Peer | SSLVerifyMode.FailIfNoPeerCert, "ssl-cert\\server.cer", "ssl-cert\\server.key", "123456", "ssl-cert\\ca.crt");
  26. HPSocketCS.Extra<ClientInfo> extra = new HPSocketCS.Extra<ClientInfo>();
  27. private string title = "Echo-SSLPackServer [ 'C' - clear list box ]";
  28. public frmServer()
  29. {
  30. InitializeComponent();
  31. }
  32. private void Form1_Load(object sender, EventArgs e)
  33. {
  34. try
  35. {
  36. this.Text = title;
  37. // 本机测试没必要改地址,有需求请注释或删除
  38. this.txtIpAddress.ReadOnly = true;
  39. // 加个委托显示msg,因为on系列都是在工作线程中调用的,ui不允许直接操作
  40. AddMsgDelegate = new ShowMsg(AddMsg);
  41. // 设置服务器事件
  42. server.OnPrepareListen += new TcpServerEvent.OnPrepareListenEventHandler(OnPrepareListen);
  43. server.OnAccept += new TcpServerEvent.OnAcceptEventHandler(OnAccept);
  44. server.OnSend += new TcpServerEvent.OnSendEventHandler(OnSend);
  45. server.OnReceive += new TcpServerEvent.OnReceiveEventHandler(OnReceive);
  46. server.OnClose += new TcpServerEvent.OnCloseEventHandler(OnClose);
  47. server.OnShutdown += new TcpServerEvent.OnShutdownEventHandler(OnShutdown);
  48. server.OnHandShake += new SSLEvent.OnHandShakeEventHandler(OnHandShake);
  49. // 设置包头标识,与对端设置保证一致性
  50. server.PackHeaderFlag = 0xff;
  51. // 设置最大封包大小
  52. server.MaxPackSize = 0x1000;
  53. SetAppState(AppState.Stoped);
  54. }
  55. catch (Exception ex)
  56. {
  57. SetAppState(AppState.Error);
  58. AddMsg(ex.Message);
  59. }
  60. }
  61. private void btnStart_Click(object sender, EventArgs e)
  62. {
  63. try
  64. {
  65. String ip = this.txtIpAddress.Text.Trim();
  66. ushort port = ushort.Parse(this.txtPort.Text.Trim());
  67. // 写在这个位置是上面可能会异常
  68. SetAppState(AppState.Starting);
  69. server.IpAddress = ip;
  70. server.Port = port;
  71. // 启动服务
  72. if (server.Start())
  73. {
  74. this.Text = string.Format("{2} - ({0}:{1})", ip, port, title);
  75. SetAppState(AppState.Started);
  76. AddMsg(string.Format("$Server Start OK -> ({0}:{1})", ip, port));
  77. }
  78. else
  79. {
  80. SetAppState(AppState.Stoped);
  81. throw new Exception(string.Format("$Server Start Error -> {0}({1})", server.ErrorMessage, server.ErrorCode));
  82. }
  83. }
  84. catch (Exception ex)
  85. {
  86. AddMsg(ex.Message);
  87. }
  88. }
  89. private void btnStop_Click(object sender, EventArgs e)
  90. {
  91. SetAppState(AppState.Stoping);
  92. // 停止服务
  93. AddMsg("$Server Stop");
  94. if (server.Stop())
  95. {
  96. this.Text = title;
  97. SetAppState(AppState.Stoped);
  98. }
  99. else
  100. {
  101. AddMsg(string.Format("$Stop Error -> {0}({1})", server.ErrorMessage, server.ErrorCode));
  102. }
  103. }
  104. private void btnDisconn_Click(object sender, EventArgs e)
  105. {
  106. try
  107. {
  108. IntPtr connId = (IntPtr)Convert.ToInt32(this.txtDisConn.Text.Trim());
  109. // 断开指定客户
  110. if (server.Disconnect(connId, true))
  111. {
  112. AddMsg(string.Format("$({0}) Disconnect OK", connId));
  113. }
  114. else
  115. {
  116. throw new Exception(string.Format("Disconnect({0}) Error", connId));
  117. }
  118. }
  119. catch (Exception ex)
  120. {
  121. AddMsg(ex.Message);
  122. }
  123. }
  124. HandleResult OnPrepareListen(IntPtr soListen)
  125. {
  126. // 监听事件到达了,一般没什么用吧?
  127. return HandleResult.Ok;
  128. }
  129. HandleResult OnAccept(IntPtr connId, IntPtr pClient)
  130. {
  131. // 客户进入了
  132. // 获取客户端ip和端口
  133. string ip = string.Empty;
  134. ushort port = 0;
  135. if (server.GetRemoteAddress(connId, ref ip, ref port))
  136. {
  137. AddMsg(string.Format(" > [{0},OnAccept] -> PASS({1}:{2})", connId, ip.ToString(), port));
  138. }
  139. else
  140. {
  141. AddMsg(string.Format(" > [{0},OnAccept] -> Server_GetClientAddress() Error", connId));
  142. }
  143. // 设置附加数据
  144. ClientInfo clientInfo = new ClientInfo();
  145. clientInfo.ConnId = connId;
  146. clientInfo.IpAddress = ip;
  147. clientInfo.Port = port;
  148. if (extra.Set(connId, clientInfo) == false)
  149. {
  150. AddMsg(string.Format(" > [{0},OnAccept] -> SetConnectionExtra fail", connId));
  151. }
  152. return HandleResult.Ok;
  153. }
  154. HandleResult OnSend(IntPtr connId, byte[] bytes)
  155. {
  156. // 服务器发数据了
  157. AddMsg(string.Format(" > [{0},OnSend] -> ({1} bytes)", connId, bytes.Length));
  158. return HandleResult.Ok;
  159. }
  160. HandleResult OnReceive(IntPtr connId, byte[] bytes)
  161. {
  162. // 数据到达了
  163. try
  164. {
  165. // 获取附加数据
  166. ClientInfo clientInfo = extra.Get(connId);
  167. if (clientInfo != null)
  168. {
  169. // clientInfo 就是accept里传入的附加数据了
  170. AddMsg(string.Format(" > [{0},OnReceive] -> {1}:{2} ({3} bytes)", clientInfo.ConnId, clientInfo.IpAddress, clientInfo.Port, bytes.Length));
  171. }
  172. else
  173. {
  174. AddMsg(string.Format(" > [{0},OnReceive] -> ({1} bytes)", connId, bytes.Length));
  175. }
  176. if (server.Send(connId, bytes, bytes.Length))
  177. {
  178. return HandleResult.Ok;
  179. }
  180. return HandleResult.Error;
  181. }
  182. catch (Exception)
  183. {
  184. return HandleResult.Ignore;
  185. }
  186. }
  187. HandleResult OnClose(IntPtr connId, SocketOperation enOperation, int errorCode)
  188. {
  189. if(errorCode == 0)
  190. AddMsg(string.Format(" > [{0},OnClose]", connId));
  191. else
  192. AddMsg(string.Format(" > [{0},OnError] -> OP:{1},CODE:{2}", connId, enOperation, errorCode));
  193. // return HPSocketSdk.HandleResult.Ok;
  194. if (extra.Remove(connId) == false)
  195. {
  196. AddMsg(string.Format(" > [{0},OnClose] -> SetConnectionExtra({0}, null) fail", connId));
  197. }
  198. return HandleResult.Ok;
  199. }
  200. HandleResult OnShutdown()
  201. {
  202. // 服务关闭了
  203. AddMsg(" > [OnShutdown]");
  204. return HandleResult.Ok;
  205. }
  206. HandleResult OnHandShake(IntPtr connId)
  207. {
  208. // ssl握手了
  209. AddMsg(string.Format(" > [{0},OnHandShake])", connId));
  210. return HandleResult.Ok;
  211. }
  212. /// <summary>
  213. /// 设置程序状态
  214. /// </summary>
  215. /// <param name="state"></param>
  216. void SetAppState(AppState state)
  217. {
  218. appState = state;
  219. this.btnStart.Enabled = (appState == AppState.Stoped);
  220. this.btnStop.Enabled = (appState == AppState.Started);
  221. this.txtIpAddress.Enabled = (appState == AppState.Stoped);
  222. this.txtPort.Enabled = (appState == AppState.Stoped);
  223. this.txtDisConn.Enabled = (appState == AppState.Started);
  224. this.btnDisconn.Enabled = (appState == AppState.Started && this.txtDisConn.Text.Length > 0);
  225. }
  226. /// <summary>
  227. /// 往listbox加一条项目
  228. /// </summary>
  229. /// <param name="msg"></param>
  230. void AddMsg(string msg)
  231. {
  232. if (this.lbxMsg.InvokeRequired)
  233. {
  234. // 很帅的调自己
  235. this.lbxMsg.Invoke(AddMsgDelegate, msg);
  236. }
  237. else
  238. {
  239. if (this.lbxMsg.Items.Count > 100)
  240. {
  241. this.lbxMsg.Items.RemoveAt(0);
  242. }
  243. this.lbxMsg.Items.Add(msg);
  244. this.lbxMsg.TopIndex = this.lbxMsg.Items.Count - (int)(this.lbxMsg.Height / this.lbxMsg.ItemHeight);
  245. }
  246. }
  247. private void txtDisConn_TextChanged(object sender, EventArgs e)
  248. {
  249. // CONNID框被改变事件
  250. this.btnDisconn.Enabled = (appState == AppState.Started && this.txtDisConn.Text.Length > 0);
  251. }
  252. private void lbxMsg_KeyPress(object sender, KeyPressEventArgs e)
  253. {
  254. // 清理listbox
  255. if (e.KeyChar == 'c' || e.KeyChar == 'C')
  256. {
  257. this.lbxMsg.Items.Clear();
  258. }
  259. }
  260. private void frmServer_FormClosed(object sender, FormClosedEventArgs e)
  261. {
  262. server.Destroy();
  263. }
  264. }
  265. [StructLayout(LayoutKind.Sequential)]
  266. public class ClientInfo
  267. {
  268. public IntPtr ConnId { get; set; }
  269. public string IpAddress { get; set; }
  270. public ushort Port { get; set; }
  271. }
  272. }