C#Socket的使用与示例

来源:互联网 发布:聊天机器人 知乎 编辑:程序博客网 时间:2024/06/05 20:03

Socket 基本概念:

   套接字是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。可以将套接字看作不同主机间的进程进行双向通信的端点,它构成了单个主机内及整个 网络间的编程界面。套接字存在于通信域中,通信域是为了处理一般的线程通过套接字通信而引进的一种抽象概念。套接字通常和同一个域中的套接字交换数据。

   套接字可以根据通信性质分类,这种性质对于用户是可见的。应用程序一般仅在同一类的套接字间进行通信。不过只要底层的通信协议允许,不同类型的套接字间也照样可以通信。套接字有两种不同的类型:流套接字和数据报套接字。

套接字工作原理:

   服务器:定义一个套接字用于监听客户端发来的信息,用int.Parse(textPORT.Text>Trim()),获取用户输入IP地址和端口号,然后,绑定IP地址和端口号。定义ServerSendMsg函数用于发送消息,定义ServerRecMsg函数用于接收消息。

    客户端:定义一个客户的套接字,获取IP地址和端口号,用Connect方法连接到服务器的网络节点,定义ClientSendMsg函数用于发送消息,定义RecMsg函数用于接收函数。

    

程序步骤及相关方法或函数

    针对Socket编程,.NET 框架的 Socket 类是 Winsock32 API 提供的套接字服务的托管代码版本。其中为实现网络编程提供了大量的方法,大多数情况下,Socket 类方法只是将数据封送到它们的本机 Win32 副本中并处理任何必要的安全检查。如果你熟悉Winsock API函数,那么用Socket类编写网络程序会非常容易,当然,如果你不曾接触过,也不会太困难,跟随下面的解说,你会发觉使用Socket类开发windows 网络应用程序原来有规可寻,它们在大多数情况下遵循大致相同的步骤。
   
   创建Socket对象的实例: 
   
   public Socket(AddressFamily addressFamily,SocketType socketType,ProtocolType protocolType);
   

addressFamily 参数指定 :Socket 使用的寻址方案,socketType 参数指定 :Socket 的类型,protocolType 参数指定: Socket 使用的协议。
   
   创建一个 Socket,用于在基于 TCP/IP 的网络(如 Internet)上通讯。
   
   Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
   
   
   若要使用 UDP 而不是 TCP,需要更改协议类型,如下面的示例所示:
   
   Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
   
   一旦创建 Socket,在客户端,你将可以通过Connect方法连接到指定的服务器,并通过Send/SendTo方法向远程服务器发送数据,而后可以通过Receive/ReceiveFrom从服务端接收数据;而在服务器端,你需要使用Bind方法绑定所指定的接口使Socket与一个本地终结点相联,并通过Listen方法侦听该接口上的请求,当侦听到用户端的连接时,调用Accept完成连接的操作,创建新的Socket以处理传入的连接请求。使用完 Socket 后,记住使用 Shutdown 方法禁用 Socket,并使用 Close 方法关闭 Socket。
   

方法及函数:
   Socket.Connect方法:建立到远程设备的连接
   public void Connect(EndPoint remoteEP)(有重载方法)
   Socket.Send 方法:从数据中的指示位置开始将数据发送到连接的 Socket。
   public int Send(byte[], int, SocketFlags);(有重载方法)
   Socket.SendTo 方法 将数据发送到特定终结点。
   public int SendTo(byte[], EndPoint);(有重载方法)
   Socket.Receive方法:将数据从连接的 Socket 接收到接收缓冲区的特定位置。
   public int Receive(byte[],int,SocketFlags);
   Socket.ReceiveFrom方法:接收数据缓冲区中特定位置的数据并存储终结点。
   public int ReceiveFrom(byte[], int, SocketFlags, ref EndPoint);
   Socket.Bind 方法:使 Socket 与一个本地终结点相关联:
   public void Bind( EndPoint localEP );
   Socket.Listen方法:将 Socket 置于侦听状态。
   public void Listen( int backlog );
   Socket.Accept方法:创建新的 Socket 以处理传入的连接请求。
   public Socket Accept();
   Socket.Shutdown方法:禁用某 Socket 上的发送和接收
   public void Shutdown( SocketShutdown how );
   Socket.Close方法:强制 Socket 连接关闭
   public void Close();


实现代码

  服务器端:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Threading;


namespace SocketServer
{
    
    class Program
    {
        private static byte[] result = new byte[1024];
        private static int myProt = 8885;//端口
        static Socket serverSocket;


        static void Main(string[] args)
        {
            IPAddress ip = IPAddress.Parse("127.0.0.1");
            serverSocket =new Socket(AddressFamily .InterNetwork,SocketType.Stream ,ProtocolType .Tcp );
            serverSocket .Bind (new IPEndPoint(ip ,myProt ));//绑定ip地址:端口
            serverSocket .Listen(10);//设置最多10个排队连接请求
            Console .WriteLine ("启动监听{0}成功", serverSocket.LocalEndPoint.ToString());
            Thread myThread=new Thread (ListenClientConnect);
            myThread .Start();
            Console .ReadLine();
        }
            //监听客户端连接
            private static void ListenClientConnect()
            {
                while (true)
                {
                    Socket clientSocket=serverSocket.Accept ();
                    clientSocket .Send (Encoding .ASCII .GetBytes ("Server Say Hello"));
                    Thread receiveThread=new Thread (ReceiveMessage);
                    receiveThread .Start (clientSocket );
                }
            }
        //接收消息
        private static void ReceiveMessage(object clientSockrt)
        {
            Socket myClientSocket=(Socket )clientSockrt ;
            while (true )
            {
                try 
                {
                    int receiveNumber=myClientSocket .Receive (result);
                    Console .WriteLine ("接收客户端{0}消息{1}",myClientSocket .RemoteEndPoint .ToString (),Encoding.ASCII .GetString(result ,0,receiveNumber));
                }
                catch (Exception ex)
                {
                    Console .WriteLine (ex .Message );
                    myClientSocket .Shutdown (  SocketShutdown.Both );
                    myClientSocket .Close ();
                    break;
                }
            }
        }
    }
}
客户端:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;




namespace SocketClient
{
    class Program
    {
        private static byte[] result = new byte[1024];


        static void Main(string[] args)
        {
            IPAddress ip = IPAddress.Parse("127.0.0.1");
            Socket clientSocket=new Socket(AddressFamily .InterNetwork ,SocketType.Stream,ProtocolType.Tcp);
            try 
            {
                clientSocket .Connect (new IPEndPoint(ip,8885));//配置服务器ip与端口
                Console.WriteLine("连接服务器成功");
            }
            catch{
                 Console .WriteLine ("连接服务器失败,请按回车键退出!");
                return;
            }
            int receiveLength=clientSocket .Receive (result );
            Console .WriteLine ("接收服务器消息:{0}",Encoding .ASCII.GetString (result ,0,receiveLength));//通过clientSocket发送数据
            for (int i=0;i<10;i++)
            {
                try 
                {
                    Thread .Sleep (1000);//等待1秒钟
                    string sendMessage="client send Message Hellp"+DateTime.Now;
                    clientSocket .Send (Encoding .ASCII.GetBytes(sendMessage ));
                    Console .WriteLine ("向服务器发送消息:{0}"+sendMessage );
                }
                catch
                {
                    clientSocket .Shutdown (  SocketShutdown.Both);
                    clientSocket .Close();
                    break;
                }
            }
            Console .WriteLine ("发送完毕,按回车键退出");
            Console .ReadLine ();
        }
    }
}