------- Windows Phone 7手机开发、.Net培训、期待与您交流! -------
服务端代码如下:
public FChatSever()
{
InitializeComponent();
TextBox.CheckForIllegalCrossThreadCalls = false;//关闭微软对文本框的跨线程操作检查
}
Thread threadWatch = null;//负责监控听客户端连接请求的线程
Socket socketWatch = null;//负责监听的套接字
private void btnBeginListen_Click(object sender, EventArgs e)
{
//------------------创建负责监听的套接字,参数(寻址协议,流连接,tcp协议)
socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//------------------获得文本框里的IP地址对象
IPAddress address = IPAddress.Parse(txtIP.Text.Trim());
//---------创建包含IP和Port的网络节点对象
IPEndPoint endpoint = new IPEndPoint(address, int.Parse(txtPort.Text.Trim()));
//------将负责监听的套接字绑定到唯一的IP和端口上
socketWatch.Bind(endpoint);
// -----设置监听的长度
socketWatch.Listen(10);
//----------线程实例化
threadWatch = new Thread(WatchConnecting);
threadWatch.IsBackground = true; //设置为后台进程
threadWatch.Start();
ShowMsg("服务器启动监听成功");
// 开始监听(执行代码,放入线程中处理了)
//Socket sokconnection = socketWatch.Accept();
//ShowMsg("客户端连接成功");
}
/// <summary>
/// 监听客户端请求的方法
/// </summary>
//保存了服务器端 所有负责和客户端通信的套接字
Dictionary<string, Socket> dict = new Dictionary<string, Socket>();
//保存了服务器端 所有负责调用通信套接字 .Recive的线程
Dictionary<string ,Thread>dictThread=new Dictionary<string,Thread>();
void WatchConnecting()
{
while (true)//持续不断的监听客户端请求
{
// 开始监听客户端请求,注意:accept 方法,会阻断当前的线程
Socket sokconnection = socketWatch.Accept();
//向列表控件中追加一个客户端的Ip端口字符串,作为客户端的唯一标识。
lbOnline.Items.Add(sokconnection.RemoteEndPoint.ToString());
//将与刻画段通信的套接字对象sokconnection添加到键值对集合中,并以客户端IP端口作为键。
dict.Add(sokconnection.RemoteEndPoint.ToString(), sokconnection);
//创建通信线程
Thread thr = new Thread(RecMsg);
thr.IsBackground = true;
thr.Start(sokconnection);
dictThread.Add(sokconnection.RemoteEndPoint.ToString(),thr);
ShowMsg("客户端连接成功"+sokconnection.RemoteEndPoint.ToString());
}
}
//服务端用来监听客户端发送过来数据的方法
void RecMsg(object socketClinetPara)
{
Socket socketClinet = socketClinetPara as Socket;
while (true)
{ //定义一个接受用的缓存区、(2M)
byte[] arrMsgRec = new byte[1024 * 1024 * 2];
// 将接收到的数据存入arrMsgRec数组中
int length = -1;
try
{
length = socketClinet.Receive(arrMsgRec);
}
catch (SocketException ex)
{
ShowMsg("异常:" + ex.Message);
//从通信套接字 集合中 删除被中断连接的 通信套接字对象
dict.Remove(socketClinet.RemoteEndPoint.ToString());
//从通信线程中删除被中断连接的 通信线程对象
dictThread.Remove(socketClinet.RemoteEndPoint.ToString());
//从列表中移除被中断的ip:Port
lbOnline.Items.Remove(socketClinet.RemoteEndPoint.ToString());
break;
}
if (arrMsgRec[0] == 0)//如果是0,则是消息。
{
//此时是将数组所有的元素都转化成字符串,而真正接受的只有几个字符而已。
string strMsgRec = System.Text.Encoding.UTF8.GetString(arrMsgRec,1 , length-1);
ShowMsg(strMsgRec);
}
else if(arrMsgRec[0]==1)//是1,则发送的是文件数据。。
{
SaveFileDialog sfd = new SaveFileDialog();//保存文件选择框对象
//用户选择文件路径
if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{ //获得要保存的文件路径
string fileSavePath = sfd.FileName;
//创建文件流,然后让文件流来根据路径创建一个文件
using (FileStream fs = new FileStream(fileSavePath, FileMode.Create))
{
fs.Write(arrMsgRec, 1, length-1);
ShowMsg("文件保存成功" + fileSavePath);
}
}
};
}
}
void ShowMsg(string msg)
{
txtMsg.AppendText(msg + "\r\n");
}
//发送消息到客户端
private void btnSend_Click(object sender, EventArgs e)
{
if(string.IsNullOrEmpty(lbOnline.Text))
{
MessageBox.Show("请选择要发送的用户!");
}
else
{
string strMsg = txtMsgSend.Text.Trim();
//将要发送的字符串转成UTF8对应的字节数组。
byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
//获得选中列表中选中的KEY
string strClientKey = lbOnline.Text;
//通过KEY,找到字典中对应的与某个客户端通信的套接字send方法,发送数据给对方。
try
{
dict[strClientKey].Send(arrMsg);
//sokconnection.Send(arrMsg);
ShowMsg("发送了数据出去" + strMsg);
}
catch (SocketException ex)
{
ShowMsg("发送时异常" + ex.Message);
}
catch (Exception ex)
{
ShowMsg("发送时异常" + ex.Message);
}
}
}
private void btnSendToAll_Click(object sender, EventArgs e)
{
string strMsg = txtMsgSend.Text.Trim();
//将要发送的字符串转成UTF8对应的字节数组。
byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
foreach (Socket s in dict.Values)
{
s.Send(arrMsg);
}
ShowMsg("群发完毕+ :)");
}
private void FChatSever_Load(object sender, EventArgs e)
{
}
}
------- Windows Phone 7手机开发、.Net培训、期待与您交流! -------