Socket聊天程序(Server)

 

 今天在VS2010上做点练习,用Socket编程写的聊天程序。

长的比较丑

 

这是服务器的主要代码: 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace _01_socketserver
{
	public partial class SocketServer : Form
	{
		Socket socketWatch = null;
		delegate void SetTextCallback(string text);
		Dictionary<string, Socket> dict = new Dictionary<string, Socket>();
		Thread receiveThread = null;

		public SocketServer()
		{
			InitializeComponent();
		}

		private void SocketServer_Load(object sender, EventArgs e)
		{
			//可以通过将 CheckForIllegalCrossThreadCalls 属性的值设置为 false 来禁用此异常
			//如果创建某控件的线程之外的其他线程试图调用该控件,则调试器会引发一个 InvalidOperationException
			//TextBox.CheckForIllegalCrossThreadCalls = false;

			//创建监听端口
			socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

			IPAddress adress = IPAddress.Parse(txtIP.Text.Trim());
			IPEndPoint endPoint = new IPEndPoint(adress, int.Parse(txtPort.Text.Trim()));
			//绑定端口
			socketWatch.Bind(endPoint);
			//设置监听队列
			socketWatch.Listen(10);
			ShowMsg("等待客户端连接...");

			//等待客户端连接
			//Socket connection = socketWatch.Accept();
			Thread thread = new Thread(new ThreadStart(WaitAccept));
			thread.IsBackground = true;
			thread.Start();

		}

		/// <summary>
		/// 显示文本信息
		/// </summary>
		/// <param name="msg"></param>
		private void ShowMsg(string msg)
		{
			if (txtShow.InvokeRequired)
			{

				SetTextCallback d = new SetTextCallback(ShowMsg); ;
				Invoke(d, new object[] { msg });
			}
			else
			{
				txtShow.AppendText(msg + "\r\n");
			}

		}

		/// <summary>
		/// 添加连接的客户端选项
		/// </summary>
		/// <param name="endpoint"></param>
		private void addEndPoint(string endpoint)
		{
			if (lbEndPoint.InvokeRequired)
			{
				SetTextCallback d = new SetTextCallback(addEndPoint);
				Invoke(d, new object[] { endpoint });
			}
			else
				lbEndPoint.Items.Add(endpoint);
		}

		/// <summary>
		/// 删除断开连接的客户端选项
		/// </summary>
		/// <param name="endpoint"></param>
		private void deleteEndPoint(int index)
		{
			if (lbEndPoint.InvokeRequired)
			{
				SetTextCallback d = new SetTextCallback(deleteEndPoint);
				Invoke(d, new object[] { index });
			}
			else
				lbEndPoint.Items.RemoveAt(index);
		}
		private void deleteEndPoint(string endpoint)
		{
			if (lbEndPoint.InvokeRequired)
			{
				SetTextCallback d = new SetTextCallback(deleteEndPoint);
				Invoke(d, new object[] { endpoint });
			}
			else
				lbEndPoint.Items.Remove(endpoint);
		}

		/// <summary>
		/// 等待连接线程函数
		/// </summary>
		private void WaitAccept()
		{
			while (true)
			{
				//等待客户端连接
				Socket connSocket = socketWatch.Accept();
				ShowMsg(connSocket.RemoteEndPoint.ToString() + "连接成功");
				//存储客户端列表
				dict.Add(connSocket.RemoteEndPoint.ToString(), connSocket);
				addEndPoint(connSocket.RemoteEndPoint.ToString());

				//接受线程启动
				receiveThread = new Thread(new ParameterizedThreadStart(ReceiveThread));
				receiveThread.IsBackground = true;
				receiveThread.Start((Object)connSocket.RemoteEndPoint.ToString());
			}

		}

		/// <summary>
		/// 接受数据线程方法
		/// </summary>
		/// <param name="obj"></param>
		private void ReceiveThread(Object obj)
		{
			while (true)
			{
				string endPoint = (string)obj;
				byte[] arrRec = new byte[1024 * 1024 * 2];
				int num = 0;
				try
				{
					num = dict[endPoint].Receive(arrRec);
					string strRec = dict[endPoint].RemoteEndPoint.ToString();
					strRec += ":" + System.Text.Encoding.Default.GetString(arrRec, 0, num);
					ShowMsg(strRec);
				}
				catch
				{
					ShowMsg(dict[endPoint].RemoteEndPoint.ToString() + "客户端关闭。");
					//关闭服务端套接字
					dict[endPoint].Close();
					//移除服务器列表项
					dict.Remove(endPoint);
					deleteEndPoint(endPoint);
					return;

				}

			}

		}

		/// <summary>
		/// 发送按钮
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void btnSend_Click(object sender, EventArgs e)
		{
			if (txtSend.Text.ToString() == "")
			{
				MessageBox.Show("发送内容不能为空!");
			}
			else
			{
				try
				{
					if (lbEndPoint.SelectedIndex == -1)
						lbEndPoint.SelectedIndex = 0;
				}
				catch
				{
					MessageBox.Show("没有可用的客户端");
					return;
				}
				//获取发送字符数组
				byte[] arrSend = System.Text.Encoding.Default.GetBytes(txtSend.Text.ToString());
				ShowMsg("to " + lbEndPoint.SelectedItem.ToString() + ":" + txtSend.Text.ToString());
				txtSend.Clear();
				try
				{
					//发送信息
					dict[lbEndPoint.SelectedItem.ToString()].Send(arrSend);
				}
				catch
				{
					ShowMsg("客户端已关闭。");
					//关闭服务端套接字
					dict[lbEndPoint.SelectedItem.ToString()].Close();
					//移除服务器列表项
					dict.Remove(lbEndPoint.SelectedItem.ToString());
					deleteEndPoint(lbEndPoint.SelectedIndex);
				}

			}//else

		}

	}
}

 

-The End-

© Jervis

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值