您的位置:首页 > 职场人生

黑马程序员_第九篇:socket学习最终代码(服务端)

2011-12-03 14:33 183 查看
---------------------- Windows Phone 7手机开发、.Net培训、期待与您交流! ----------------------

首先理清思路
服务端首先一个线程是用来接收连接请求的,他有一个while循环,用来不断接收请求,其中用一个socket
接收到请求后,为这个来连接的客户端创建一个线程,调用一个socket,用来和他通信
由于还会有客户端来连接,所以放在一个循环里,每循环一次,就创建一个线程,里面一个socket。
应为每次创建的线程和socket会覆盖上一个线程和socket,所以不能用全局变量,应该把每次的线程和socket存在dictionary里

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;//ip,ipaddress,ipEndPoint(ip和端口)类

using System.Threading;
using System.IO;

namespace MyChatRoomServer
{
public partial class FChatServer : Form
{
public FChatServer()
{
InitializeComponent();
TextBox.CheckForIllegalCrossThreadCalls = false;
}
Thread threadWatch = null;
Dictionary<string, Thread> dictThread = new Dictionary<string, Thread>();
Socket watchSocket = null;
private void btnBeginListen_Click(object sender, EventArgs e)
{
//创建服务端负责监听的套接字,参数(连接方式ipv4,使用流的形式,协议用tcp协议传输数据)
watchSocket = 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));
//将负责监听的套接字绑定到ip和port上
watchSocket.Bind(endPoint);
//设置监听队列的长度
watchSocket.Listen(10);
threadWatch = new Thread(WatchConnection);
threadWatch.IsBackground = true;
threadWatch.Start();

ShowMsg("服务器启动监听成功!");

}
Dictionary<string, Socket> dict = new Dictionary<string, Socket>();
void WatchConnection()
{

while (true)
{
//设置套接字开始监听,并接返回一个新的套接字对象,用于和客户端连接,注意accept方法会阻断当前线程
Socket sokConnection = watchSocket.Accept();
lbOlineIp.Items.Add(sokConnection.RemoteEndPoint.ToString());
//向dictionary中添加
dict.Add(sokConnection.RemoteEndPoint.ToString(), sokConnection);
//设计一个线程负责运行每个连接客户端的socket
Thread thr = new Thread(recMsg);
thr.IsBackground = true;
thr.Start(sokConnection);
//把线程加入到字典里
dictThread.Add(sokConnection.RemoteEndPoint.ToString(), thr);

ShowMsg("连接客户端成功!" + sokConnection.RemoteEndPoint.ToString());
}

}
//服务端负责监听客户端发送来数据的方法
void recMsg(object socketConnectionPara)
{
Socket socketClient = socketConnectionPara as Socket;
while (true)
{
byte[] arrMsgRec = new byte[1024 * 1024 * 2];
int length = -1;
try
{
length = socketClient.Receive(arrMsgRec);
}
catch (SocketException ex)
{
ShowMsg("异常:" + ex.Message);
dict.Remove(socketClient.RemoteEndPoint.ToString());
dictThread.Remove(socketClient.RemoteEndPoint.ToString());
lbOlineIp.Items.Remove(socketClient.RemoteEndPoint.ToString());
break;
}
catch (Exception ex)
{
ShowMsg("异常:" + ex.Message);
break;
}
if (arrMsgRec[0] == 0)//判断发送过来的一个数据是0则是文本
{
string steMsgRce = System.Text.Encoding.UTF8.GetString(arrMsgRec, 1, length-1);
ShowMsg(steMsgRce);
}
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 FChatServer_Load(object sender, EventArgs e)
{

}

private void btnSend_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(lbOlineIp.Text))
{
MessageBox.Show("请选择要发送信息的好友");
}
else
{
string strMsg = txtSendMsg.Text.Trim();
//将要发送的字符串转换为utf8对应的字节数组
byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);

//获得列表中选中的ip
string strClientKey = lbOlineIp.Text;
//通过key找到dictionary中的socket的send方法发送信息
try
{
dict[strClientKey].Send(arrMsg);
}
catch (SocketException ex)
{
ShowMsg("发送时异常:" + ex.Message);
}
catch (Exception ex)
{
ShowMsg("发送时异常:" + ex.Message);
}
//sokConnection.Send(arryMsg);
ShowMsg("发送了数据:" + strMsg);
}
}

private void lbOlineIp_SelectedIndexChanged(object sender, EventArgs e)
{

}

private void btnSendAll_Click(object sender, EventArgs e)
{
string strMsg = txtSendMsg.Text.Trim();
//将要发送的字符串转换为utf8对应的字节数组
byte[] arryMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
foreach (Socket s in dict.Values)
{
s.Send(arryMsg);
ShowMsg("群发成功");
}
}
}
}


---------------------- Windows Phone 7手机开发、.Net培训、期待与您交流! ----------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: