用PASCAL实现的一个服务器端,基于SELECT模形,(学习形)
program tcpser;{$APPTYPE CONSOLE}
uses
SysUtils, Windows, WinSock;
var
sListen,sCli: TSocket;
allfd, rdfd:TFDSet;
n:Integer;
buf:array[0..1024] of Char;
i, len:Integer;
cliaddr:sockaddr_in;
////////////////////////////////////////////////////////////////////////////////
// 初始化WINSOCKET
//
function initsocket:Boolean;
var
sAddr:sockaddr_in;
WSA:WSAData;
nCode:Integer;
begin
Result := False;
nCode := WSAStartup(MakeWord(1,1), WSA);
if nCode <> 0 then
begin
Writeln('wsastartup failed.');
Exit;
end;
sAddr.sin_family := AF_INET;
sAddr.sin_port := htons(2000);
sAddr.sin_addr.S_addr := inet_addr(PChar('127.0.0.1'));//本机
sListen := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//TCP流SOCKET
if sListen = invalid_socket then
begin
Writeln('socket failed.!');
WSACleanup;
exit;
end;
ncode := bind(sListen, saddr, SizeOf(sAddr));
if ncode = socket_error then
begin
Writeln('bind socket failed.!');
closesocket(sListen);
WSACleanup;
Exit;
end;
ncode := listen(sListen, 5);
if nCode = socket_error then
begin
writeln('listen failed.!');
closesocket(sListen);
WSACleanup;
Exit;
end;
Result := True;
end;
////////////////////////////////////////////////////////////////////////////////
// 主程序入口
//
begin
if not initsocket then
begin
Writeln('start server failed.!');
Exit;
end else
begin
writeln('server start succeeded.!');
end;
FD_ZERO(allfd);
FD_SET(sListen, allfd);
while True do
begin
FD_ZERO(rdfd);
rdfd := allfd;
n := select(0, @rdfd, nil, nil, nil);
if n > 0 then
begin
for i := 0 to allfd.fd_count - 1 do
begin
if FD_ISSET(allfd.fd_array[i], rdfd) then
begin
//接受新的客户端连接
if allfd.fd_array[i] = sListen then
begin
len := SizeOf(cliaddr);
sCli := accept(sListen, @cliaddr, @len);
if sCli = INVALID_SOCKET then
begin
Writeln('accept failed.!');
Break;
end;
Writeln('new client connectioned server.!');
Writeln('IP: '+inet_ntoa(cliaddr.sin_addr));
Writeln('PORT: '+ inttostr(ntohs(cliaddr.sin_port)));
FD_SET(sCli, allfd); //加入集合组
Continue;
end else
begin
n := recv(allfd.fd_array[i], buf, 1024, 0);
if n > 0 then
begin
Writeln('Client: '+buf);
end else
if n = 0 then
begin
len :=SizeOf(cliaddr);
getpeername(allfd.fd_array[i], cliaddr, len);
Writeln('closeed by '+ inet_ntoa(cliaddr.sin_addr));
closesocket(allfd.fd_array[i]);
FD_CLR(allfd.fd_array[i], allfd);
end else
if n < 0 then
begin
Writeln('recv error!');
end;
end;
end;
end;
end else
if n < 0 then
begin
Writeln('select failed.!');
Break;
end;
end;
for i := 0 to allfd.fd_count - 1 do
begin
closesocket(allfd.fd_array[i]);
FD_CLR(allfd.fd_array[i], allfd);
end;
closesocket(sListen);
WSACleanup;
end.
目前还有一个问题,,就是在服务器端应该如何实现从键盘输入来响应SELECT,,在C语言中可以用STDIN标准输入来实现,PASCAL中希望有人指教