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)

            {

                //

            }

        }



        /// <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)

        {

             //写入日志代码

        }

    }

/// 线程执行体,转发消息 

        /// </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(); 



   } 



   } 



namespace UDPServer

{

    class Program

    {

        static void Main(string[] args)

        {

            int recv;

            byte[] data = new byte[1024]; 



            //构建TCP 服务器



            //得到本机IP,设置TCP端口号         

            IPEndPoint ipep = new IPEndPoint(IPAddress.Any , 8001);

            Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram , ProtocolType.Udp);



            //绑定网络地址

            newsock.Bind(ipep);



            Console.WriteLine("This is a Server, host name is {0}",Dns.GetHostName());



            //等待客户机连接

            Console.WriteLine("Waiting for a client...");



            //得到客户机IP

            IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);

            EndPoint Remote = (EndPoint)(sender);

            recv = newsock.ReceiveFrom(data, ref Remote);

            Console .WriteLine ("Message received from {0}: ", Remote.ToString ());

            Console .WriteLine (Encoding .ASCII .GetString (data ,0,recv ));



            //客户机连接成功后,发送欢迎信息

            string welcome = "Welcome ! ";



            //字符串与字节数组相互转换

            data  = Encoding .ASCII .GetBytes (welcome );



            //发送信息

            newsock .SendTo (data ,data.Length ,SocketFlags .None ,Remote );

            while (true )

            {

                data =new byte [1024];

                //发送接受信息

                recv =newsock.ReceiveFrom(data ,ref Remote);

                Console .WriteLine (Encoding .ASCII .GetString (data ,0,recv));

                newsock .SendTo (data ,recv ,SocketFlags .None ,Remote );

            }

        }



        }

    }

try

                    {

                        Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);  //向此网段发广播包

                          int UDPListenerPort = 8082;

                        IPAddress broadcast = IPAddress.Parse("192.168.0.255"); //此处根据IP及子网掩码改为相应的广播IP

                        string ts = "This is UPD string for sending";

                        byte[] sendbuf = Encoding.ASCII.GetBytes(ts);

                        IPEndPoint ep = new IPEndPoint(broadcast, UDPListenerPort);

                        s.SendTo(sendbuf, ep);



                    }

                    catch (Exception e)

                    {}

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Net;

using System.Net.Sockets;



namespace UDPClient

{

    class Program

    {

        static void Main(string[] args)

        {

            byte[] data = new byte[1024];

            string input ,stringData;



            //构建TCP 服务器



            Console.WriteLine("This is a Client, host name is {0}", Dns.GetHostName());



            //设置服务IP,设置TCP端口号

            IPEndPoint ipep = new IPEndPoint(IPAddress .Parse ("127.0.0.1") , 8001);



            //定义网络类型,数据连接类型和网络协议UDP

            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);



            string welcome = "Hello! ";

            data = Encoding.ASCII.GetBytes(welcome);

            server.SendTo(data, data.Length, SocketFlags.None, ipep);

            IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);

            EndPoint Remote = (EndPoint)sender;



            data = new byte[1024];

            int recv = server.ReceiveFrom(data, ref Remote);

            Console.WriteLine("Message received from {0}: ", Remote.ToString());

            Console.WriteLine(Encoding .ASCII .GetString (data,0,recv));

            while (true)

            {

                input = Console .ReadLine ();

                if (input =="exit")

                    break ;

                server .SendTo (Encoding .ASCII .GetBytes (input ),Remote );

                data = new byte [1024];

                recv = server.ReceiveFrom(data, ref Remote);

                stringData = Encoding.ASCII.GetString(data, 0, recv);

                Console.WriteLine(stringData);

            }

            Console .WriteLine ("Stopping Client.");

            server .Close ();            

        }



        }

    }
C#UDP的多路广播组的发送和接收 
下列范例使用 UdpClient,在通讯端口11000传送UDP 资料包至多点传送位址群组 224.268.100.2。它传送命令列上指定的信息字串。
using System;  

using System.Net;  

using System.Net.Sockets;  

using System.Text;  



public class UDPMulticastSender {  



private static IPAddress GroupAddress =  

IPAddress.Parse("224.168.100.2");  

private static int GroupPort = 11000;  



private static void Send( String message) {  

UdpClient sender = new UdpClient();  

IPEndPoint groupEP = new IPEndPoint(GroupAddress,GroupPort);  



try {  

Console.WriteLine("Sending datagram : {0}", message);  

byte[] bytes = Encoding.ASCII.GetBytes(message);  



sender.Send(bytes, bytes.Length, groupEP);  



sender.Close();  



} catch (Exception e) {  

Console.WriteLine(e.ToString());  

}  



}  



public static int Main(String[] args) {  

Send(args[0]);  



return 0;  

}  

}  
//TCPClient

//TCPClient 类提供了一种使用 TCP 协议连接到某个端点的简化方法。它还通过 NetworkStream 对象展现在连接过程中

//读取或写入的数据。请参见下面从 QuickStart 文档中摘录的日期/时间客户机示例。



//使用 C# 编写

using System;

using System.Net;

using System.Net.Sockets;

using System.IO;

using System.Text;

class Client

{

public static void Main(String[] args)

{

TCPClient tcpc = new TCPClient();

Byte[] read = new Byte[32];

if (args.Length != 1)

{

Console.WriteLine(“请在命令行中指定服务器名称”);

return;

}

String server = args[0];

// 验证服务器是否存在

if (DNS.GetHostByName(server) == null)

{

Console.WriteLine(“找不到服务器:” + 服务器);

return;

}

// 尝试连接到服务器

if (tcpc.Connect(server, 13) == -1)

{

Console.WriteLine(“无法连接到服务器:” + 服务器);

return;

}

// 获取流

Stream s = tcpc.GetStream();

// 读取流并将它转换为 ASCII 码形式

int bytes = s.Read(read, 0, read.Length);

String Time = Encoding.ASCII.GetString(read);

// 显示数据

Console.WriteLine(“已接收到的” + 字节 + “字节”);

Console.WriteLine(“当前日期和时间是:” + 时间);

tcpc.Close();

}

}



//TCPListener

//TCPListener 类便于在来自某个客户机的 TCP 连接的特定套接字上进行侦听的工作。请参见下面包括在 QuickStart 文档

//中的日期/时间服务器示例。



使用 C# 编写

using System;

using System.Net;

using System.Net.Sockets;

using System.Text;

class Server

{

public static void Main()

{

DateTime now;

String strDateLine;

Encoding ASCII = Encoding.ASCII;

// 在端口 13 进行侦听

TCPListener tcpl = new TCPListener(13);

tcpl.Start();

Console.WriteLine(“正在等待客户进行连接”);

Console.WriteLine(“请按 Ctrl+c 退出...”);

while (true)

{

// 接收会阻塞,直到有人连接上

Socket s = tcpl.Accept();

// 获取当前的日期和时间并将它连接成一个字符串

now = DateTime.Now;

strDateLine = now.ToShortDateString() + " " +

now.ToLongTimeString();

// 将该字符串转换成一个字节数组并发送它

Byte[] byteDateLine =

ASCII.GetBytes(strDateLine.ToCharArray());

s.Send(byteDateLine, byteDateLine.Length, 0);

Console.WriteLine(“发送” + strDateLine);

}

}

}




本文转载:CSDN博客