标题:用PASCAL实现的一个服务器端,基于SELECT模形,(学习形)
只看楼主
gdzhan
Rank: 2
等 级:论坛游民
帖 子:90
专家分:14
注 册:2007-4-15
结帖率:66.67%
 问题点数:0 回复次数:1 
用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中希望有人指教
搜索更多相关主题的帖子: 服务器 学习 SELECT PASCAL 
2010-01-22 21:30
kt23
Rank: 2
等 级:论坛游民
帖 子:13
专家分:10
注 册:2010-4-17
得分:0 
多线程
2010-04-17 20:57



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-296285-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.344716 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved