zoukankan      html  css  js  c++  java
  • socket套接字

    进程通信机制。用来描述IP地址和端口,是一个通信链的句柄。

    两种类型:

    流式:一种面向连接的socket,针对面向连接的tcp服务应用,安全,但效率低。

    数据报式:一种无连接的socket,对应于无连接的udp服务应用。不安全(丢失),顺序混乱,在接收端要分析重排及要求重发,但效率高。

    服务端与客户端通讯过程

    服务端

      申请一个socket--绑定到一个ip地址和端口--开启监听,等待接收和连接

    客户端

      申请一个socket--连接服务器(指明ip地址和端口号)

    服务端接到连接请求后产生一个新的socket与客户端建立连接并进行通讯。原监听socket继续监听。

    注意:

    至少要定义一个要连接的远程主机的ip和端口号。

    端口号必须在1到65535之间,最好在1024以后。

    要连接的远程主机必须正在监听指定端口。

    一个socket一次只能连接一台主机。

    socket关闭后无法再次使用。

    每个socket对象只能一台远程主机连接。如果想连接到多台远程主机,必须创建多个socket对象。

    //简单服务器与客户端通信实现

    //服务端

    //在构造函数里初始化完组件后取消下跨线程检查。

    Control.CheckForIllegalCrossThreadCalls=false;

    //定义一个全局的socket

    Socket sockServer;

    //创建一个字典集合保存与客户端通信的套接字 界面上放置一个listview显示当前连接的客户端ip终结点 listViewOnline

    Dictionary<string,Socket> dictSocket=new Dictionary<string,Socket>();

    socketServer=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.TCP);

    IPAddress address=IPAddress.Parse(127.0.0.1);

    IPEndPoint endPoint=new IPEndPoint(address,Convert.ToInt32(8001));

    //监听套接字绑定到端口上

    socketServer.Bind(endPoint);

    //设置监听队列的最大长度

    socketServer.Listen(10);

    //服务已启动。。。

    //可以开启一个线程监听并接收客户端连接请求

    Thread threadWatch=new Thread(WatchConnet);

    threadWatch.IsBackground=true;

    threadWatch.Name="watchThread";

    threadWatch.Start();

    //WatchConnect监听连接请求

    bool isWatch=true;

    void WatchConnect()

    {

    try

    {

    while(isWatch)

    {

    //监听并接收客户端连接请求,如果有连接过来则返回一个负责通信的套接字

    Socket sokMsg=sockServer.Accept();

    //获取客户端终结点

    string clientKey=sokMsg.RemoteEndPoint.ToString();

    //添加到listview中

    listViewOnline.Items.Add(clientKey,clientKey,"");

    //添加到集合中

    dictSocket.Add(clientKey,sokMsg);

    //有客户端连接

    //可以创建一个通信线程

    Thread threadRecMsg=new Thread(WatchMsg);

    threadRecMsg.IsBackground=true;

    threadRecMsg.Name="threadRecMsg";

    threadRecMsg.Start(sokMsg);

    }

    }

    catch(Exception ex){}

    }

    //接收客户端发来的消息

    void WatchMsg(object sok)

    {

    Socket sokMsg=null;

    try

    {

    while(isWatch)

    {

    sokMsg= sok as Socket;

    byte[] arrMsg=new byte[1024*1024];

    int length=sokMsg.Receive(arrMsg);

    string msg=Encoding.UTF8.GetString(arrMsg,0,arrMsg.Length);

    //客户端发送的内容:msg

    }

    }

    catch(Exception ex){}

    }

    //向指定客户端发送消息

    if(listViewOnline.SelectedItems.Count>0)

    {

    string clientKey=listViewOnline.SelectedItems[0].Text;

    //判断通信套接字是否包含此客户端的网络节点

    if(dictSocket.ContainsKey(clientKey))

    {

    string strMsg="发送给客户端"+clientKey+"的消息";

    byte[] arrMsg=Encoding.UTF8.GetBytes(strMsg);

    //根据节点找到字典中对应的通信套接字对象,并调用send方法向客户端发送消息。

    dictSocket[clientKey].Send(arrMsg);

    }

    }

    //客户端

    //创建一个全局socket

    Socket sokClient;

    sokClient=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

    IPEndPoint endpoint=new IPEndPoint(IPAddress.Parse(127.0.0.1),int.Parse(8001));

    try

    {

    sokClient.Connect(endpoint);

    //可以创建一个线程与服务端通信

    Thread threadClient=new Thread(WatchMsgFromServer);

    threadClient.IsBackground=true;

    threadClient.Name="WatchMsgFromServer";

    threadClient.Start();

    }

    catch(Exception ex){}

    //监听通信

    void WatchMsgFromServer()

    {

    try

    {

    while(true)

    {

    byte[] arrMsg=new byte[1024*1024];

    int realLength=sokClient.Receive(arrMsg);

    string strMsg=Encoding.UTF8.GetString(arrMsg,0,realLength);

    //服务器发送的内容:strMsg

    }

    }

    catch(Exception ex){}

    }

    //给服务端发送消息

    string msgSend=“给服务端发送的消息”;

    byte[] arrMsg=Encoding.UTF8.GetBytes(msgSend);

    sokClient.Send(arrMsg);

  • 相关阅读:
    Java-判断一个数是不是素数
    Sublime快捷键
    python
    全排列
    python
    python
    OpenCV 实现图像结构相似度算法 (SSIM 算法)
    C++
    C++
    NFA 转 DFA
  • 原文地址:https://www.cnblogs.com/buzhidaojiaoshenme/p/6825235.html
Copyright © 2011-2022 走看看