我在delphi用了Tsocket做服务器端通讯端口 ,它默认是阻塞方式,可是为什么阻塞不好用呢,接受一次连接后阻塞就不好用了呢,程序代码如下:
wVersionRequested:=MAKEWORD(2,2);
erro:=WSAStartup(wVersionRequested,wsd);
if erro<>0 then
WSACleanup;
if (LOBYTE(wsd.wVersion)<>2) then
WSACleanup;
if(HIBYTE(wsd.wVersion)<>2) then
WSACleanup;
V_CONN_ID := socket(AF_INET,SOCK_STREAM,0);
cmd:=0;
rtn:=ioctlsocket(V_CONN_ID,FIONBIO,cmd);
if(rtn<>0) then
exit;
if(V_CONN_ID=INVALID_SOCKET) then
exit;
ZeroMemory(@m_rcvaddr,sizeof(m_rcvaddr));
ZeroMemory(@m_acceptaddr,sizeof(m_acceptaddr));
m_rcvaddr.sin_family := PF_INET;
m_rcvaddr.sin_addr.s_addr := INADDR_ANY;
m_rcvaddr.sin_port := htons(strtoint(form1.listen_port));
rtn:=bind(V_CONN_ID,m_rcvaddr,sizeof(m_rcvaddr));
if(rtn<>0) then
exit;
rtn:=listen(V_CONN_ID,1);
if(rtn<>0) then
exit;
while (not form1.rec_stop_flag ) do
begin
V_ACCEPT_ID:=accept(V_CONN_ID,m_acceptaddr,@m_accept_len);//???????
end;
wVersionRequested:=MAKEWORD(2,2);
erro:=WSAStartup(wVersionRequested,wsd);
if erro<>0 then
WSACleanup;
if (LOBYTE(wsd.wVersion)<>2) then
WSACleanup;
if(HIBYTE(wsd.wVersion)<>2) then
WSACleanup;
V_CONN_ID := socket(AF_INET,SOCK_STREAM,0);
cmd:=0;
rtn:=ioctlsocket(V_CONN_ID,FIONBIO,cmd);
if(rtn<>0) then
exit;
if(V_CONN_ID=INVALID_SOCKET) then
exit;
ZeroMemory(@m_rcvaddr,sizeof(m_rcvaddr));
ZeroMemory(@m_acceptaddr,sizeof(m_acceptaddr));
m_rcvaddr.sin_family := PF_INET;
m_rcvaddr.sin_addr.s_addr := INADDR_ANY;
m_rcvaddr.sin_port := htons(strtoint(form1.listen_port));
rtn:=bind(V_CONN_ID,m_rcvaddr,sizeof(m_rcvaddr));
if(rtn<>0) then
exit;
rtn:=listen(V_CONN_ID,1);
if(rtn<>0) then
exit;
while (not form1.rec_stop_flag ) do
begin
V_ACCEPT_ID:=accept(V_CONN_ID,m_acceptaddr,@m_accept_len);//???????
end;
procedure SocketServerOp(p: Pointer); stdcall
var
s_server,s_client: TSocket;
nameLength: Integer;
server,client: sockaddr_in; //tpye:sockaddr_in
WSAData: TWSAData;
procedure SelectSocket;
var
ErrNum,nfds,iret:integer;
setR:TFDSet;
begin
ErrNum:=1;
while ErrNum<10 do
begin
nfds:=0;
FD_ZERO(setR);
FD_SET(s_server,setR);
// 最后一位参数为nil表示阻塞直到有连接请求 iRet = select(iu, setR, nil, nil, timeout);
iRet := select(nfds,@setR, nil,nil,nil);
if iRet= SOCKET_ERROR then
inc(ErrNum)
else if iRet<>0 then break;
end;
end;
begin
while true do
begin
server.sin_family:=AF_INET;
server.sin_addr.S_addr :=INADDR_ANY;
server.sin_port:=htons(CommPort);
if WSAStartup($101, WSAData)<>0 then exit;
s_server:=socket(PF_INET,SOCK_STREAM,0);
try
if (s_server=INVALID_SOCKET) then exit;
if bind(s_server,server,sizeof(server))<>0 then exit;
if listen(s_server,20)<>0 then exit;
nameLength:= sizeof(client);
while true do
begin
SelectSocket;
s_client:= accept(s_server,@client,@nameLength);
if s_client=INVALID_SOCKET then exit;
try
//--处理过程
except
CloseSocket(s_client);
CloseSocket(s_server);
WSACleanup;
break;
end;
end;
except
CloseSocket(s_server);
WSACleanup;
end;
end;
end;