您的位置:首页 > 理论基础 > 计算机网络

学习笔记:delphi实现网络通信之select模型

2011-04-28 15:18 393 查看
说明:所有的winsock的定义用的是jwawinsock2。(整个包的下载:http://blog.delphi-jedi.net/home/)

主要函数:select

目的:允许那些想要避免在套接字调用上阻塞的应用程序有能力管理多个套接字。

函数定义:select(nfds:integer;readfds:Pfd_set;writefds:Pfd_set;exceptfds:Pfd_set;timeout:Ptimeval)

套接集合:FD_SET结构

PFD_SET=^Fd_set

Fd_set=record

fd_count:integer;

fd_array:array[0..FD_SETSIZE-1] of Tsocket;

end;{FD_SETSIZE系统默认为64.也就是系统默认管理64个套接字。实际可以定义到1000。}

关于FD_SET集合操作函数。

FD_ZERO(SET:PFD_SET) 初始化set为空集合。集合在使用前应该总是清空。

FD_CLR(s:TSOCKET;set:PFD_SET) 从set移除套接字。

FD_ISSETs(S:TSOCKET;SET:PFD_SET) 检查s是不是set的成员,如果是返回TRUE。

FD_SET(S:TSOCKET;set:PFD_SET)添加套接字到集合。

delphi代码:

program Proserver;
//控制台程序。
{$APPTYPE CONSOLE}

uses
JwaWinsock2,Windows,SysUtils;

var
nPort:UINT;
sListen,sNew:TSocket;
socket_in,addrRemote:sockaddr_in;
fdSocket,fdRead:fd_set;
i,nAddrLen:integer;
szText:array[0..255] of AnsiChar;
procedure initsock;
var
v_wsadata:WSAData;
sockversion:Cardinal;
begin
sockversion:=MAKEWORD(2,2);
try
if WSAStartup(sockversion,v_wsadata)<>0 then
Exit;

except
Exit;
end;
end;
procedure cleansock;
begin
WSACleanup();
end;
begin
initsock;
nport:=4567;
sListen:=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
socket_in.sin_family:=AF_INET;
socket_in.sin_port:=htons(nPort);
socket_in.sin_addr.S_addr:=INADDR_ANY;

//进行SOCKET绑定到本地机器
if bind(sListen,psockaddr(@socket_in),SizeOf(socket_in))=socket_error then
begin
writeln('Failed bind()');
Exit;
end
else
begin
Writeln('SOCKET绑定成功。');
end;

//进入监听模式
Writeln('程序进入监听状态......');
listen(sListen,5);

//select模型处理过程
//1、初始化一个套接字集合fdsocket,添加监听套接字句柄到这个集合。
FD_ZERO(fdSocket);
_FD_SET(sListen,fdSocket);

//进行等待状态中。。。。。。
Writeln('进入无限循环状态。。。。。');
while True do
begin
// 2、将FDSOCKET集合的一个拷贝FDREAD传递给SELECT函数。
fdRead:=fdSocket;
if select(0,@fdread,nil,nil,nil)>0 then
begin
for i:=0 to fdSocket.fd_count-1 do
begin
if FD_ISSET(fdSocket.fd_array[i],fdRead) then
begin
if fdSocket.fd_array[i]=sListen then
begin
if fdSocket.fd_count<FD_SETSIZE then
begin
nAddrLen:=SizeOf(addrRemote);
sNew:=accept(sListen,psockaddr(@addrRemote),@nAddrlen);
_FD_SET(sNew,fdSocket);
Writeln('接收到连接:'+strpas(inet_ntoa(addrRemote.sin_addr)));
end
else
begin
Writeln('连接太多,超出系统要求。');
Continue;
end;
end
else
begin
if recv(fdSocket.fd_array[i],szText,SizeOf(szText),0)>0 then
begin
Writeln('接收的数据是:'+strpas(sztext));
end
else
begin
closesocket(fdSocket.fd_array[i]);
FD_CLR(fdSocket.fd_array[i],fdSocket);
Writeln('当前连接已判断。');
end;
end;
end;
end;
end
else
begin
Writeln('Failed select().');
Break;
end;
end;
cleansock;
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐