public class XmlSocket {
//异步socket诊听
// Incoming data from client.从客户端传来的数据 public static string data = null;
// Thread signal.线程 用一个指示是否将初始状态设置为终止的布尔值初始化 ManualResetEvent 类的新实例。
public static ManualResetEvent allDone = new ManualResetEvent(false); //static void Main(string[] args) //{
// StartListening(); //}
public static void StartListening() {
// Data buffer for incoming data. 传入数据缓冲 byte[] bytes = new Byte[1024];
// Establish the local endpoint for the socket. 建立本地端口 // The DNS name of the computer
// running the listener is \"host.contoso.com\".
IPAddress ipAddress;
String ipString = ConfigurationManager.AppSettings.Get(\"SocketIP\"); if (ipString==null || ipString ==String.Empty) {
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName()); ipAddress = ipHostInfo.AddressList[0]; } else {
ipAddress = IPAddress.Parse(ipString); }
int port;
String portString =
ConfigurationManager.AppSettings.Get(\"SocketPort\");
if (portString==null || portString==String.Empty) {
port = 11001; } else
{
port = int.Parse(portString); }
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port);
// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.绑定端口和数据 try {
listener.Bind(localEndPoint); listener.Listen(100);
while (true) {
// Set the event to nonsignaled state.设置无信号状态的事件 allDone.Reset();
// Start an asynchronous socket to listen for connections.重新 启动异步连接
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
// Wait until a connection is made before continuing.等待连接创建后继续
allDone.WaitOne(); } }
catch (Exception e) { // } }
public static void AcceptCallback(IAsyncResult ar) { try {
// Signal the main thread to continue.接受回调方法 该方法的此节向主应用程序线程发出信号,
//让它继续处理并建立与客户端的连接 allDone.Set();
// Get the socket that handles the client request.获取客户端请求句柄
Socket listener = (Socket)ar.AsyncState; Socket handler = listener.EndAccept(ar); // Create the state object.
StateObject state = new StateObject(); state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); }
catch (Exception e) { // } }
/// /// 与接受回调方法一样,读取回调方法也是一个 AsyncCallback 委托。 /// 该方法将来自客户端套接字的一个或多个字节读入数据缓冲区,然后再次调用 BeginReceive 方法,直到客户端发送的数据完成为止。 /// 从客户端读取整个消息后,在控制台上显示字符串,并关闭处理与客户端的连接的服务器套接字。 ///
/// IAsyncResult 委托 public static void ReadCallback(IAsyncResult ar) { try {
String content = String.Empty;
// Retrieve the state object and the handler socket创建自定义的状态对象 from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState; Socket handler = state.workSocket;//处理的句柄 // Read data from the client socket. 读出 int bytesRead = handler.EndReceive(ar); if (bytesRead > 0) {
//业务代码
string result = DoSomeThing(...); String len =
Encoding.UTF8.GetBytes(result).Length.ToString().PadLeft(8, '0'); log.writeLine(len);
Send(len + result, handler); }
}
catch (Exception e) { // }
}
private static void Send(String data, Socket handler) { try {
// Convert the string data to byte data using UTF8 encoding. byte[] byteData = Encoding.UTF8.GetBytes(data); // Begin sending the data to the remote device. handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler); }
catch (Exception e) { // } }
/// ///
///
private static void SendCallback(IAsyncResult ar) { try {
// Retrieve the socket from the state object. Socket handler = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.向远端发送数据 int bytesSent = handler.EndSend(ar); StateObject state = new StateObject(); state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,new AsyncCallback(ReadCallback), state);
handler.Shutdown(SocketShutdown.Both); handler.Close(); }
catch (Exception e)
{ //
} }
public static void StopListening() {
allDone.Close(); log.close(); }
///
///
private static string DoSomething(int i) {
//具体业务代码,返回需要返回的字符串信息 }
///
/// 写入内容 public static void WriteLog(string strLog) {
//写入日志代码 }
}
/// 线程执行体,转发消息
///
/// 传递给线程执行体的用户名,用以与用户通信 private void ThreadFunc(object obj) {
//通过转发表得到当前用户套接字
Socket clientSkt = _transmit_tb[obj] as Socket; //主循环
while (true) { try
{ //接受第一个数据包。
//由于程序逻辑结构简单,所以在这里对客户机发送的第一个包内容作逐一判断, //这里的实现不够优雅,但不失为此简单模型的一个解决之道。 byte[] packetBuff = new byte[_maxPacket]; clientSkt.Receive(packetBuff);
string _str =
Encoding.Unicode.GetString(packetBuff).TrimEnd('\\0'); //如果是发给不在线好友的信息
if (_str.StartsWith(\"cmd::FriendMessage\")) {
string UserName =
_str.Substring(\"cmd::FriendMessage\".Length, 20).Trim(); string MessageS =
_str.Substring(\"cmd::FriendMessage\".Length + 20, _str.Length - \"cmd::FriendMessage\".Length - 20);
SaveMessage(obj as string, UserName, MessageS); continue; }
//如果是离线请求
if (_str.StartsWith(\"cmd::RequestLogout\")) {
_transmit_tb.Remove(obj);
UpdateFriendList((string)obj, false, \"\");
// string svrlog = string.Format(\"[系统消息]用户 {0} 在 {1} 已断开... 当前在线人数: {2}\\r\\n\\r\\n\ // Console.WriteLine(svrlog); //向所有客户机发送系统消息
//foreach (DictionaryEntry de in _transmit_tb) //{
// string _clientName = de.Key as string; // Socket _clientSkt = de.Value as Socket;
// _clientSkt.Send(Encoding.Unicode.GetBytes(svrlog)); //}
Thread.CurrentThread.Abort(); }
//如果是请求好友列表
if (_str.StartsWith(\"cmd::RequestFriendList\")) {
SerializeFriendList(obj, clientSkt); // 将该用户不在线时的信息发送给用户
DataTable TabMessage = ReadMessage(obj as string); if (TabMessage != null) {
foreach (DataRow myrow in TabMessage.Rows) {
if (myrow[\"SendUserName\"].ToString() == \"System::Message\")
{
clientSkt.Send(Encoding.Unicode.GetBytes(myrow[\"Message\"].ToString())); } else {
clientSkt.Send(Encoding.Unicode.GetBytes(\"cmd::FriendMessage\" + myrow[\"SendUserName\"].ToString().PadRight(20, ' ') + myrow[\"Message\"].ToString())); } }
} //这里不需要再继续接受后继数据包了,跳出当前循环体。 continue; }
////如果是请求好友列表
//if (_str.StartsWith(\"cmd::RequestOnLineList\")) //{
// byte[] onlineBuff = SerializeOnlineList(); // //先发送响应信号,用户客户机的判断 //
clientSkt.Send(Encoding.Unicode.GetBytes(\"cmd::RequestOnLineList\")); // clientSkt.Send(onlineBuff);
// //这里不需要再继续接受后继数据包了,跳出当前循环体。 // continue; //} //查找用户
if (_str.StartsWith(\"Find::FindFriend\")) {
DataTable TabFind = TabUser.Clone(); DataRow [] FindRow =null ;
string UserName = _str.Substring(\"Find::FindFriend\".Length, _str.Length - \"Find::FindFriend\".Length);
if (UserName.Equals(\"Find::WhoOnLine\")) { //看谁在线
FindRow = TabUser.Select(\" ZX = 1\"); }
else//精确查找 {
FindRow = TabUser.Select(\"UserName = '\" + UserName + \"'\"); }
foreach (DataRow myrow in FindRow) {
TabFind.ImportRow(myrow); }
clientSkt.Send(Encoding.Unicode.GetBytes(\"Find::FindFriend\")); IFormatter format = new BinaryFormatter(); MemoryStream stream = new MemoryStream(); format.Serialize(stream, TabFind); stream.Position = 0;
byte[] ret = new byte[_maxPacket]; int count = 0;
count = stream.Read(ret, 0, _maxPacket); while (count >0) {
clientSkt.Send(ret);
count = stream.Read(ret, 0, _maxPacket); }
clientSkt.Send(Encoding.Unicode.GetBytes(\"Find::FindFriendEnd\")); stream.Close(); TabFind = null;
FindRow = null; //这里不需要再继续接受后继数据包了,跳出当前循环体。
continue; } //请求添加好友
if (_str.StartsWith(\"Find::AddFriendAsk\")) {
string UserName =
_str.Substring(\"Find::AddFriendAsk\".Length, _str.Length - \"Find::AddFriendAsk\".Length);
//通过转发表查找接收方的套接字 if (_transmit_tb.Count != 0 && _transmit_tb.ContainsKey(UserName)) {
Socket receiverSkt = _transmit_tb[UserName] as Socket;
receiverSkt.Send(Encoding.Unicode.GetBytes(\"Find::AddFriendAsk\" + obj as string));
}
//这里不需要再继续接受后继数据包了,跳出当前循环体。 continue; }
//回复答应添加好友
if (_str.StartsWith(\"Find::AddFriendYes\")) {
string UserName =
_str.Substring(\"Find::AddFriendYes\".Length, _str.Length - \"Find::AddFriendYes\".Length); //// 保存数据
DataTable TabmyFriend = new DataTable() ; //保存该用户
TabmyFriend.ReadXml(MyPath + \"\\\\UserFriend\\\\\" + obj as string + \".xml\");
DataRow newRow = TabmyFriend.NewRow(); newRow[\"UserName\"] = UserName; TabmyFriend.Rows.Add(newRow);
TabmyFriend.WriteXml(MyPath + \"\\\\UserFriend\\\\\" + obj as string + \".xml\", XmlWriteMode.WriteSchema, false); //保存其好友
TabmyFriend = new DataTable();
TabmyFriend.ReadXml(MyPath + \"\\\\UserFriend\\\\\" + UserName + \".xml\");
DataRow newRow1 = TabmyFriend.NewRow(); newRow1[\"UserName\"] = obj as string; TabmyFriend.Rows.Add(newRow1);
TabmyFriend.WriteXml(MyPath + \"\\\\UserFriend\\\\\" + UserName + \".xml\", XmlWriteMode.WriteSchema, false); TabmyFriend = null;
SerializeFriendList(obj, clientSkt); //\"开始\"按钮事件
private void button1_Click(object sender, System.EventArgs e) {
//取得预保存的文件名
string fileName=textBox3.Text.Trim();
//远程主机
string hostName=textBox1.Text.Trim();
//端口
int port=Int32.Parse(textBox2.Text.Trim());
//得到主机信息
IPHostEntry ipInfo=Dns.GetHostByName(hostName);
//取得IPAddress[]
IPAddress[] ipAddr=ipInfo.AddressList;
//得到ip
IPAddress ip=ipAddr[0];
//组合出远程终结点
IPEndPoint hostEP=new IPEndPoint(ip,port);
//创建Socket 实例
Socket socket=new
Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); try {
//尝试连接
socket.Connect(hostEP); }
catch(Exception se) {
MessageBox.Show(\"连接错误\"+se.Message,\"提示信息
,MessageBoxButtons.RetryCancel,MessageBoxIcon.Information); }
//发送给远程主机的请求内容串
string sendStr=\"GET / HTTP/1.1\\r\\nHost: \" + hostName +
\"\\r\\nConnection: Close\\r\\n\\r\\n\";
//创建bytes字节数组以转换发送串
byte[] bytesSendStr=new byte[1024];
//将发送内容字符串转换成字节byte数组
bytesSendStr=Encoding.ASCII.GetBytes(sendStr); try {
//向主机发送请求
socket.Send(bytesSendStr,bytesSendStr.Length,0); }
catch(Exception ce) {
MessageBox.Show(\"发送错误:\"+ce.Message,\"提示信息
,MessageBoxButtons.RetryCancel,MessageBoxIcon.Information); }
//声明接收返回内容的字符串
string recvStr=\"\";
//声明字节数组,一次接收数据的长度为1024字节
byte[] recvBytes=new byte[1024];
//返回实际接收内容的字节数
int bytes=0;
//循环读取,直到接收完所有数据
while(true) {
bytes=socket.Receive(recvBytes,recvBytes.Length,0);
//读取完成后退出循环
if(bytes〈=0)
break;
//将读取的字节数转换为字符串
recvStr+=Encoding.ASCII.GetString(recvBytes,0,bytes); }
//将所读取的字符串转换为字节数组
byte[] content=Encoding.ASCII.GetBytes(recvStr); try {
//创建文件流对象实例
FileStream fs=new
FileStream(fileName,FileMode.OpenOrCreate,FileAccess.ReadWrite);
//写入文件
fs.Write(content,0,content.Length); }
catch(Exception fe) {
MessageBox.Show(\"文件创建/写入错误:\"+fe.Message,\"提示信息\",MessageBoxButtons.RetryCancel,MessageBoxIcon.Information); }
//禁用Socket
socket.Shutdown(SocketShutdown.Both);
//关闭Socket
socket.Close(); }
}
转载自网站:
http://topic.csdn.net/u/20080623/08/4bbd2475-45f1-42e3-a613-16b094759ade.html?85362
因篇幅问题不能全部显示,请点此查看更多更全内容