网络编程之TCP异步群聊:服务器端代码
最近朋友建议我写一些关于微软云技术的博客留给学校下一届的学生们看,怕下一届的MSTC断档。于是我也觉的有这个必要。写了几篇博客之后,我觉得也有必要把这一年的学习内容放在博客做个纪念,就这样写了本篇博客。
该程序可以在公共网络上运行,只要输入服务器的IP地址即可。
程序不是很难,由于时间过了一年多了,现在也不好详细讲解了。就贴一下代码,程序还是很容易理解的,看英文单词就知道代码的意思了。
客户端代码在:http://blog.****.net/arsenal1109389480/article/details/12400385
第一步:建一个Winform程序
第二步:添加一个类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Sockets; namespace server { class StreamObject { public TcpClient client; public NetworkStream netStream; public byte[] readBytes; public byte[] writeBytes; public StreamObject(TcpClient client) { this.client = client; netStream = client.GetStream(); readBytes = new byte[client.ReceiveBufferSize]; writeBytes = new byte[client.SendBufferSize]; } public void InitReadArray() { readBytes = new byte[client.ReceiveBufferSize]; } public void InitWriteArray() { writeBytes = new byte[client.SendBufferSize]; } } }
第三步:服务器代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Net; using System.Net.Sockets; using System.Threading; using System.IO; namespace server { public partial class ServerMain : Form { System.Collections.ArrayList clientList = new System.Collections.ArrayList(); Thread ServerThread; private delegate void SetListBoxStatuCallback(string str); private SetListBoxStatuCallback setlistboxstatucallback; private delegate void SetListBoxRecieveCallback(string str); private SetListBoxRecieveCallback setlistboxrecievecallback; bool isExit = false; private EventWaitHandle allDone = new EventWaitHandle(false, EventResetMode.ManualReset); public ServerMain() { InitializeComponent(); setlistboxstatucallback = new SetListBoxStatuCallback(SetListboxStatu); setlistboxrecievecallback = new SetListBoxRecieveCallback(SetListboxRecieve); } private void ServerMain_Load(object sender, EventArgs e) { startlisten.Enabled = true; stoplisten.Enabled = false; labelstatu.Text = "等待运行......"; } private void startlisten_Click(object sender, EventArgs e) { startlisten.Enabled = false; stoplisten.Enabled = true; ThreadStart ts = new ThreadStart(AcceptConnect); ServerThread = new Thread(ts); ServerThread.Start(); } private void AcceptConnect() { TcpListener listener; IPAddress IP = IPAddress.Parse("127.0.0.1"); listener = new TcpListener(IP, Convert.ToInt32(portText.Text)); listener.Start(); while (isExit == false) { try { allDone.Reset(); AsyncCallback callback = new AsyncCallback(AcceptTcpClient); listBoxStatus.Invoke(setlistboxstatucallback, "开始等待用户连接"); listener.BeginAcceptTcpClient(callback, listener); allDone.WaitOne(); } catch(Exception err) { MessageBox.Show(err.Message); } } } private void AcceptTcpClient(IAsyncResult ar) { try { allDone.Set(); TcpListener myListener = (TcpListener)ar.AsyncState; TcpClient myclient = myListener.EndAcceptTcpClient(ar); listBoxRecieve.Invoke(setlistboxrecievecallback, "已接受客户连接" + myclient.Client.RemoteEndPoint); StreamObject streamobject = new StreamObject(myclient); clientList.Add(streamobject); SendString("用户"+myclient.Client.RemoteEndPoint+"进入服务器"); streamobject.netStream.BeginRead(streamobject.readBytes, 0, streamobject.readBytes.Length, ReadCallback, streamobject); } catch(Exception err) { MessageBox.Show(err.Message); } } private void ReadCallback(IAsyncResult ar) { try { StreamObject streamobject = (StreamObject)ar.AsyncState; int count = streamobject.netStream.EndRead(ar); SendString(string.Format("[来自{0}]{1}", streamobject.client.Client.RemoteEndPoint, System.Text.Encoding.UTF8.GetString(streamobject.readBytes, 0, count))); if (isExit == false) { streamobject.InitReadArray(); streamobject.netStream.BeginRead(streamobject.readBytes, 0, streamobject.readBytes.Length, ReadCallback, streamobject); } } catch(Exception err) { MessageBox.Show(err.Message); } } private void SendString(string str) { StreamObject streamobject; for(int i=0;i<clientList.Count;i++) { streamobject = (StreamObject)clientList[i]; try { streamobject.writeBytes = System.Text.Encoding.UTF8.GetBytes(str); streamobject.netStream.BeginWrite(streamobject.writeBytes, 0, streamobject.writeBytes.Length, new AsyncCallback(SendCallback), streamobject); streamobject.netStream.Flush(); } catch { clientList.RemoveAt(i); SendString(string.Format("用户{0}离开服务器。",streamobject.client.Client.RemoteEndPoint)); streamobject.netStream.Close(); } } } private void SendCallback(IAsyncResult ar) { StreamObject streamobject = (StreamObject)ar.AsyncState; try { streamobject.netStream.EndWrite(ar); } catch (Exception err) { MessageBox.Show(err.Message); } } private void SetListboxStatu(string str) { listBoxStatus.Items.Add(str); listBoxStatus.SelectedIndex = listBoxStatus.Items.Count - 1; listBoxStatus.ClearSelected(); } private void SetListboxRecieve(string str) { listBoxRecieve.Items.Add(str); listBoxRecieve.SelectedIndex = listBoxRecieve.Items.Count - 1; listBoxRecieve.ClearSelected(); } private void stoplisten_Click(object sender, EventArgs e) { //使线程自动结束 isExit = true; //将事件状态设置为终止状态,允许一个或者多个等待线程继续 //从而使线程正常结束 allDone.Set(); startlisten.Enabled = true; stoplisten.Enabled = false; } } }