Socket通讯

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)= 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)             {                 //             }         }         /// <summary>         /// 与接受回调方法一样,读取回调方法也是一个 AsyncCallback 委托。         /// 该方法将来自客户端套接字的一个或多个字节读入数据缓冲区,然后再次调用 BeginReceive 方法,直到客户端发送的数据完成为止。         /// 从客户端读取整个消息后,在控制台上显示字符串,并关闭处理与客户端的连接的服务器套接字。         /// </summary>         /// <param name="ar">IAsyncResult 委托</param>         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)             {                 //             }         }         /// <summary>         /// 发送         /// </summary>         /// <param name="ar"></param>         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();         }         /// <summary>         /// 具体处理业务的方法         /// </summary>         /// <returns></returns>         private static string DoSomething(int i)         {             //具体业务代码,返回需要返回的字符串信息         }         /// <summary>         /// 写日志方法         /// </summary>         /// <param name="strLog">写入内容</param>         public static void WriteLog(string strLog)         {              //写入日志代码         }     } *******************************************************************************

{ IPHostEntry ipHostInfo

/// 线程执行体,转发消息         /// </summary>         /// <param name="obj">传递给线程执行体的用户名,用以与用户通信 </param>         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", obj, DateTime.Now, _transmit_tb.Count);                       //  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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值