Delphi Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
델파이 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
FreePascal/Lazarus
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
델마당
볼랜드포럼 광고 모집

델파이 Q&A
Delphi Programming Q&A
[10595] 델파이 소스를 C++Builder소스로 변환좀....^^;
김민재 [jae0202] 1827 읽음    2006-03-30 13:06
unit ChatServerUnit;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, Buttons, ComCtrls, ScktComp, Winsock, StrUtils;
type
  PClientRecord = ^ClientRecord;
  ClientRecord = record
    UserId: string[100];
    UserNick: string[100];
    Error: integer;
  end;

  TChatServerMFrm = class(TForm)
    BasePanel: TPanel;
    ChatMsg: TRichEdit;
    LeftPanel: TPanel;
    MsgPanel: TPanel;
    UserList: TListBox;
    TopPanel: TPanel;
    ServerPort: TLabeledEdit;
    BtnStart: TBitBtn;
    BtnStop: TBitBtn;
    ServerSocket: TServerSocket;
    NumClient: TStaticText;
    ClientText: TStaticText;
    Panel1: TPanel;
    Panel2: TPanel;
    Edit1: TEdit;
    procedure BtnStartClick(Sender: TObject);
    procedure ServerSocketClientConnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerSocketClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerSocketClientDisconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerSocketClientError(Sender: TObject;
      Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
      var ErrorCode: Integer);
    procedure FormCreate(Sender: TObject);
    procedure BtnStopClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    ClientList: TList;
    procedure BroadCast(BroadMsg: string);
    procedure BroadCastExceptOne(BroadMsg: string; ExceptId: string);
  end;

var
  ChatServerMFrm: TChatServerMFrm;

implementation
{$R *.dfm}

// returns ISP assigned IP
function LocalIP : string;
type
  TaPInAddr = array [0..10] of PInAddr;
  PaPInAddr = ^TaPInAddr;
var
  phe: PHostEnt;
  pptr: PaPInAddr;
  Buffer: array [0..63] of char;
  I: integer;
  GInitData: TWSADATA;
begin
  WSAStartup($101, GInitData);
  Result := '';
  GetHostName(Buffer, SizeOf(Buffer));
  phe :=GetHostByName(buffer);
  if phe = nil then Exit;
  pptr := PaPInAddr(Phe^.h_addr_list);
  I := 0;
  while pptr^[I] <> nil do begin
    result:=StrPas(inet_ntoa(pptr^[I]^));
    Inc(I);
  end;
  WSACleanup;
end;

procedure TChatServerMFrm.BtnStartClick(Sender: TObject);
begin
  if ServerPort.Text = '' then begin
    MessageDlg('포트정보가 없습니다.'#13#13'접속할 서버의 포트번호를 입력하세요', mtWarning, [mbOK], 0);
    ServerPort.SetFocus;
    Exit;
  end;

  ServerSocket.Port := StrToInt(ServerPort.Text);
  ServerSocket.Active := true;

  BtnStart.Enabled := False;
  BtnStop.Enabled := True;
end;

procedure TChatServerMFrm.ServerSocketClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
var
  ClientData: PClientRecord;
begin
  GetMem(ClientData, Sizeof(ClientRecord));
  Socket.Data := ClientData;
  ClientData^.UserId := '';
  ClientData^.UserNick := '';
  ClientData^.Error := 0;
  NumClient.Caption := IntToStr(StrToInt(NumClient.Caption)+1);
end;

procedure TChatServerMFrm.ServerSocketClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
var
  ClientData: PClientRecord;
  i: integer;
begin
  NumClient.Caption := IntToStr(StrToInt(NumClient.Caption)-1);
  ClientData := PClientRecord(Socket.Data);
  ClientData.Error := 1;

  BroadCastExceptOne('DISC|'+ClientData^.UserId, ClientData^.UserId);

  for i:=0 to UserList.Items.Count-1 do begin
    if (LeftStr(UserList.Items[i], Pos('[',UserList.Items[i])-1)) = ClientData^.UserId then
    begin
      UserList.Items.Delete(i);
      break;
    end;
  end;
 
  FreeMem(PClientRecord(Socket.Data));
end;

procedure TChatServerMFrm.BroadCast(BroadMsg: string);
var
  i: integer;
begin
  for i:=0 to ServerSocket.Socket.ActiveConnections-1 do
  begin
    if PClientRecord(ServerSocket.Socket.Connections[i].Data).Error <>1 then
    begin
      ServerSocket.Socket.Connections[i].SendText(BroadMsg+#10);
    end;
  end;
end;

procedure TChatServerMFrm.ServerSocketClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  RevMsg: string;
  Packet, PacketDetail: TStringList;
  i, j: integer;
  tmpClientData: PClientRecord;
begin
  RevMsg := Socket.ReceiveText;

  Packet := TStringList.Create;
  PacketDetail := TStringList.Create;

  try
    Packet.Clear;
    ExtractStrings([#10], [' '], PChar(RevMsg), Packet);

    for i:=0 to Packet.Count-1 do
    begin
      ChatMsg.Lines.Add(Packet.Strings[i]);
      PacketDetail.Clear;
      ExtractStrings(['|'], [' '], PChar(Packet.Strings[i]), PacketDetail );

      // CONN 패킷
      if PacketDetail.Strings[0] = 'CONN' then
      begin
        for j:=0 to ServerSocket.Socket.ActiveConnections-2 do begin
          tmpClientData := PClientRecord(ServerSocket.Socket.Connections[j].Data);
         
          if (tmpClientData^.UserId = PacketDetail[1]) then begin   // id 중복검사
            Socket.SendText('SYSM|'+PacketDetail[1]+'는 이미 존재하는 아이디입니다.');
            Socket.Close;
            Exit;
          end;
          Socket.SendText('MEMB|'+tmpClientData^.UserId+'|'+tmpClientData^.UserNick+#10);
        end;

        UserList.Items.Add(PacketDetail.Strings[1]+'['+PacketDetail.Strings[2]+']');

        BroadCast(Packet.Strings[i]);
        (PClientRecord(Socket.Data)).UserId := PacketDetail.Strings[2];
        (PClientRecord(Socket.Data)).UserNick := PacketDetail.Strings[1];
      end;

      // MESG 패킷
      if PacketDetail.Strings[0] = 'MESG' then
      begin
        BroadCast(Packet.Strings[i]);
      end;

      // WHIS 패킷
      if PacketDetail.Strings[0] = 'WHSP' then
      begin
        for j:=0 to ServerSocket.Socket.ActiveConnections-1 do
          if (PClientRecord(ServerSocket.Socket.Connections[j].Data)^.UserId = PacketDetail[1]) or (PClientRecord(ServerSocket.Socket.Connections[j].Data)^.UserId = PacketDetail[2]) then
            ServerSocket.Socket.Connections[j].SendText(Packet.Strings[i]+#10);
      end;

      // NICK 패킷
      if PacketDetail.Strings[0] = 'NICK' then
      begin
        BroadCast(Packet.Strings[i]);

        for j:=0 to UserList.Items.Count-1 do begin
          if (LeftStr(UserList.Items[j], Pos('[',UserList.Items[j])-1)) = PacketDetail[1] then
          begin
            UserList.Items[j] := PacketDetail[1]+'['+PacketDetail[2]+']';
            break;
          end;
        end;
      end;
    end;
  finally
    Packet.Free;
    PacketDetail.Free;
  end;
end;

procedure TChatServerMFrm.ServerSocketClientError(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
  Socket.Close;
  ErrorCode := 0;
end;

procedure TChatServerMFrm.FormCreate(Sender: TObject);
begin
  Edit1.Text := LocalIp;
end;

procedure TChatServerMFrm.BtnStopClick(Sender: TObject);
begin
  ServerSocket.Active := False;
  UserList.Clear;
 
  BtnStart.Enabled := True;
  BtnStop.Enabled := False;
end;

procedure TChatServerMFrm.BroadCastExceptOne(BroadMsg, ExceptId: string);
var
  i: integer;
begin
  for i:=0 to ServerSocket.Socket.ActiveConnections-1 do
  begin
    if (PClientRecord(ServerSocket.Socket.Connections[i].Data).Error <> 1) and (PClientRecord(ServerSocket.Socket.Connections[i].Data).UserId <> ExceptId) then
    begin
      ServerSocket.Socket.Connections[i].SendText(BroadMsg+#10);
    end;
  end;

end;

end.

-참고-
**글구 혹시 델파이 소스를 c++소스로 변환해주는 툴은 없는지요?...**

+ -

관련 글 리스트
10595 델파이 소스를 C++Builder소스로 변환좀....^^; 김민재 1827 2006/03/30
10601     Re:델파이 소스를 C++Builder소스로 변환좀....^^; 박지훈.임프 1659 2006/03/30
10606         Re:Re:델파이 소스를 C++Builder소스로 변환좀....^^; 김민재 1322 2006/03/31
10666             Re:Re:Re:C++ 언어 구조체 ☆~ 1284 2006/04/22
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.