読者です 読者をやめる 読者になる 読者になる

Delphi XE4でWinsockを使ってみる

Delphi Windows

以前Delphi2009で書いてた。

以前書いたのと比べて、XE4でusesのパッケージが変わったのと、AnsiStringを使わずにTBytesを使うように変更してみた。
TBytesよりPByte(ポインタ)のほうが慣れてるかもしれん..

program EchoServer;

{$APPTYPE CONSOLE}

uses
  System.SysUtils
  , System.Classes
  , Winapi.Windows
  , Winapi.Winsock
  ;

const
  PORT = 5000;
  ADDRESS = '127.0.0.1';

var
  WSData: WSAData;
  ServerSocket, ClientSocket: TSocket;
  ServerAddress, ClientAddress: TSockAddr;
  ReceivedBuffer: array[0..255] of Byte;
  BufferReceivedSize: Integer;
  AddrLength: Integer;
begin
  if WSAStartup($202, WSData) <> 0 then
  begin
    WriteLn('Winsock Error.');
    Exit;
  end;
  WriteLn('Listen: ', ADDRESS, ':', PORT);
  ServerSocket := socket(AF_INET, SOCK_STREAM, 0);
  if ServerSocket = INVALID_SOCKET then
  begin
    WriteLn('Invalid socket.');
    WSACleanup;
    Exit;
  end;
  try
    ServerAddress.sin_family := AF_INET;
    ServerAddress.sin_port := htons(PORT);
    ServerAddress.sin_addr.S_addr := inet_addr(ADDRESS);
    bind(ServerSocket, ServerAddress, SizeOf(ServerAddress));
    while True do
    begin
      // 待受開始
      listen(ServerSocket, 1);
      AddrLength := SizeOf(ClientAddress);
      ClientSocket := accept(ServerSocket, @ClientAddress, @AddrLength);
      while True do
      begin
        ZeroMemory(@ReceivedBuffer, SizeOf(ReceivedBuffer));
        BufferReceivedSize := recv(ClientSocket, ReceivedBuffer, SizeOf(ReceivedBuffer), 0);
        if BufferReceivedSize = SOCKET_ERROR then
        begin
          WriteLn('SocketError.');
          Break;
        end;
        // クライアント側での切断
        if BufferReceivedSize = 0 then
        begin
          WriteLn('Connection closed.');
          Break;
        end;
        send(ClientSocket, ReceivedBuffer, Length(ReceivedBuffer), 0);
      end;
    end;
  finally
    WSACleanup;
  end;
end.