1. 程式人生 > >用pascal寫的最簡單的winsock程式 --收藏轉貼

用pascal寫的最簡單的winsock程式 --收藏轉貼


我把socket程式設計教程的第一個例子改寫了一下伺服器接受客戶資訊,再反送回去
實際上是直接呼叫win api在delphi4下用命令列編譯dcc32 -cc server1.pas
用windows自帶的telnet測試

server1.pas:
program server1;

uses windows,winsock;

const myport=1414;//預定義口

{type
 sockaddr_in = record
  case Integer of
   0: (sin_family: u_short;
     sin_port: u_short;
     sin_addr: TInAddr;
     sin_zero: array[0..7] of Char);
   1: (sa_family: u_short;
     sa_data: array[0..13] of Char)
 end;
 TSockAddrIn = sockaddr_in;
 PSOCKADDR = ^TSockAddr;
 TSockAddr = sockaddr_in;

 WSAData = record // !!! also WSDATA
  wVersion: Word;
  wHighVersion: Word;
  szDescription: array[0..WSADESCRIPTION_LEN] of Char;
  szSystemStatus: array[0..WSASYS_STATUS_LEN] of Char;
  iMaxSockets: Word;
  iMaxUdpDg: Word;
  lpVendorInfo: PChar;
 end;
 TWSAData = WSAData;

end
}

var str:string;
  s,ns:TSocket;//type:u_int|integer;
  ver:word;
  rece:TWSAData;//type:WSAData;
  wsstatus:integer;//winsocket_status;
  i,pktlen:integer;
  szd:array[0..WSADESCRIPTION_LEN] of Char;
  szs:array[0..WSASYS_STATUS_LEN] of Char;
  server:TSockAddr;//tpye:sockaddr_in
  client:PSockAddr;//type:^sockaddr_in
  namelen:PInteger;//type:^Integer;
  buf:array[0..1023] of char;

begin
  ver:=514; 
  write('WSAStartup = ');
  try
    wsstatus:=WSAStartup(ver,rece);
    //初始化winsock;在windows下是必須的過程
    writeln(wsstatus);//winsock狀態,0代表成功
    if wsstatus=0 then
    begin
      writeln;
      writeln('********************************************************************************');
      //以下顯示winsock狀態
      write('wVersion = ');
      writeln(rece.wVersion);
      write('wHighVersion = ');
      writeln(rece.wHighVersion);
      write('iMaxSockets = ');
      writeln(rece.iMaxSockets);
      write('iMaxUdpDg = ');
      writeln(rece.iMaxUdpDg);
      writeln('szDescription is ');
      for i:=0 to WSADESCRIPTION_LEN do
        write(szd[i]);
      writeln;
      writeln('szSystemStatus is ');
      for i:=0 to WSASYS_STATUS_LEN do
        write(szs[i]);
      writeln;
      writeln('********************************************************************************');
    end;

    write('socket = ');
    s:=socket(AF_INET,SOCK_STREAM,0);
    //第一步,建立伺服器的socket,0表示成功
    writeln(s);
    if s<0 then exit;

    write('bind = ');
    server.sin_family := AF_INET;
    server.sin_port := htons(myport);
    server.sin_addr.s_addr := INADDR_ANY;
    wsstatus:=bind(s,server,sizeof(server));
    //第二步,繫結,0表示成功
    writeln(wsstatus);
    if wsstatus<>0 then exit;

    write('listen = ');
    wsstatus:=listen(s,5);
    //第三步,監聽
    writeln(wsstatus);
    if wsstatus<>0 then exit;

    write('accept = ');
    new(client);
    new(namelen);
    namelen^:=sizeof(client^);
    ns:=accept(s,client,namelen);
    //第四步,等待接收
    //注:bind時傳遞的是sockaddr_in結構的資料,accept時是兩個指標!!!
    if ns=-1 then //以下可以做成多執行緒過程
   begin
    writeln(-1);
    exit;
   end
   else
   begin
    writeln(ns);
    pktlen:=0;
    writeln('recv');
    repeat
      pktlen:= recv(ns,buf,1024,0);//接收資料
        //pktlen=為接收長度,0表示斷開聯接,<0表示失敗
    sleep(1);
    write(pktlen:5);
    if pktlen>0 then
    begin
       i:=send(ns,buf,pktlen,0);//返回資料
    end;
   until pktlen<1;//迴圈直到客戶斷開聯接

     end;
  finally
    writeln;
    writeln('********************************************************************************');
    writeln('Press to exit winsocket');
    readln(str);
    wsstatus:=WSACleanup();//退出winsocket;
    write('WSACleanup = ');
    writeln(wsstatus);
  end;
  writeln;
  writeln('Press to exit');
  readln(str);
end.