zoukankan      html  css  js  c++  java
  • WinSock学习笔记3:Select模型

    WinSock学习笔记3:Select模型

    unit Unit1;

    interface

    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, WinSock, ExtCtrls;

    type
      TWorkThread 
    = class(TThread)
      
    private
        FClientSocket: TSocket;
        FMemo: TMemo;
        FBuff: array [
    0..10] of Char;
        procedure ShowRecv;
      
    protected
        procedure Execute;
    override;
      
    public
        constructor Create(ClientSocket: TSocket; Memo: TMemo);
      end;

      TForm1 
    = class(TForm)
        Memo1: TMemo;
        Button1: TButton;
        Timer1: TTimer;
        procedure Button1Click(Sender: TObject);
        procedure Timer1Timer(Sender: TObject);
      
    private
        { Private declarations }
      
    public
        { Public declarations }
      end;

    var
      Form1: TForm1;
      ServerSocket: TSocket;
      ClientSocket: TSocket;

    implementation

    {$R 
    *.dfm}

    procedure TForm1.Button1Click(Sender: TObject);
    var
      WSData: WSAData;

      LocalAddr: TSockAddrIn;
      SocketMode: Integer;
    begin
      
    //初始化Winsock
      WSAStartUp($202, WSData);
      
    //创建套接字
      ServerSocket:= Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

      
    //设置LocalAddr的参数
      LocalAddr.sin_family:= AF_INET;   //IPV4族
      LocalAddr.sin_addr.S_addr:= Inet_addr('127.0.0.1');//点分字符串格式的IP地址转换为互联网格式
      LocalAddr.sin_port:= Htons(1077); //Host To Net Short,主机字节顺序转为网络字节顺序
      
    //绑定本机IP地址、端口,绑定之前先设置好LocalAddr的参数
      Bind(ServerSocket, LocalAddr, SizeOf(LocalAddr));

      
    //设置WinSock I/O模式
      SocketMode:= 1;
      IoCtlSocket(ServerSocket, FIONBIO, SocketMode);

      
    //开始监听,最多同时监听5个连接
      Listen(ServerSocket, 5);
      Timer1.Enabled:
    = True;
    end;

    { TWorkThread }

    constructor TWorkThread.Create(ClientSocket: TSocket; Memo: TMemo);
    begin
      inherited Create(False);

      FClientSocket:
    = ClientSocket;
      FMemo:
    = Memo;
    end;

    procedure TWorkThread.Execute;
    var
      FDSet: TFDSET;
    begin
      inherited;

      FreeOnTerminate:
    = True;

      
    while not Terminated do
      begin
        FD_Zero(FDSet);       
    //初始化FDSet
        FD_SET(FClientSocket, FDSet);  //将FClientSocket加入FDSet
        if Select(0, @FDSet, nil, nil, nil) > 0 then  //测试FDSet中是否有可读的连接
        begin
          
    if Recv(FClientSocket, FBuff, SizeOf(FBuff), 0> 0 then  //如果收到消息就显示出来
            Synchronize(ShowRecv)
          
    else
            Break;
        end;
      end;
    end;

    procedure TWorkThread.ShowRecv;
    begin
      FMemo.Lines.Add(FBuff);
    end;

    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
      ClientSocket:
    = Accept(ServerSocket, nil, nil);
      
    if ClientSocket <> INVALID_SOCKET then
        TWorkThread.Create(ClientSocket, Memo1);
    end;

    end.

    1.使用Select模型,要定义一个FDSet结构,将客户端Socket加入该结构,用Select函数轮询测试该Socket的读写状态。FDSet结构:

        typedef struct fd_set {
          u_int fd_count;                                     
          SOCKET fd_array[FD_SETSIZE];          
        } fd_set;

    2.操作FDSet结构有4个预定义的宏:

           FD_CLR(s, *set)
    Removes the descriptor s from set.
           FD_ISSET(s, *set)
    Nonzero if s is a member of the set. Otherwise, zero.
           FD_SET(s, *set)
    Adds descriptor s to set.
           FD_ZERO(*set)
    Initializes the set to the null set.

    3.上面的代码为了方便,用了一个Timer来Accept,然后为每一个连接进来的Socket创建线程,在线程中用Select测试是否可读,为使代码简单,没有处理异常的代码。


    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/dropme/archive/2009/09/09/4534748.aspx

  • 相关阅读:
    完美数据迁移-MongoDB Stream的应用
    补习系列(3)-springboot中的几种scope
    补习系列(2)-springboot mime类型处理
    hdfs directory item limit
    git-format-patch
    SPARK-18560
    hdfs OutOfMemoryError
    hdfs 路径不支持‘:’
    java.io.UTFDataFormatException: encoded string too long:
    scala-maven-plugin excludes
  • 原文地址:https://www.cnblogs.com/tc310/p/1837937.html
Copyright © 2011-2022 走看看