Socket通讯

来源:互联网 发布:淘宝违规支付宝冻结 编辑:程序博客网 时间:2024/04/29 23:43

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

原创粉丝点击