델파이. Delphi를 사용하여 메일 보내기

표준 Win2000/XP 메시지 전송 명령 net send를 사용하기 위한 인터페이스를 제공하는 프로그램을 개발하십시오. 사용자가 수신자의 주소, 메시지 텍스트 및 보낼 메시지 수를 지정할 수 있도록 허용합니다. 또한 다른 컴퓨터로부터 메시지 수신을 차단하는 기능도 제공합니다.

양식 개발

만들다 새 프로젝트델파이. 양식 제목(캡션 속성)을 Net Sender로 변경합니다. 양식의 왼쪽 가장자리를 따라 세 개의 레이블 범주 구성 요소를 하나씩 배치합니다. 기준 Caption 속성을 IP 주소:, 메시지: 및 수량:으로 설정합니다.

각 레이블 옆에 편집 범주 구성 요소를 배치합니다. 기준. 상위 IP(이름 속성)의 이름을 지정하고 텍스트 속성에 값 192.168.0.1을 할당합니다.; 중간 필드의 이름을 txt로 지정하고 Text 속성을 일부 기본 메시지 텍스트에 할당합니다. 맨 아래 필드의 이름을 How로 지정하고 Text 속성을 1로 설정합니다.

나열된 구성 요소 아래에 Category Checkbox 구성 요소를 배치합니다. 기준. 이름을 secure로 지정하고 Caption 속성을 메시지 수신 비활성화로 설정하고 Checked 속성을 True로 설정합니다.

양식 맨 아래에 버튼(버튼 카테고리 구성 요소)을 배치합니다. 기준), Caption 속성을 Send로 설정합니다. 타이머도 필요합니다(구성요소 타이머 카테고리 체계), Interval 속성을 10으로 설정해야 합니다.

결과 모양은 그림과 일치해야 합니다. 15.1.

쌀. 15.1. 프로그램이 메시지를 보낼 양식 지역 네트워크

프로그램 코드 개발

우선, 모든 설정을 읽고 메시지를 보내는 자체 폭탄 절차를 작성해 보겠습니다. 이 프로시저를 양식 클래스의 비공개 멤버로 선언합니다.

정수 유형의 전역 변수 i도 필요합니다.

이제 구현 섹션에서 폭탄 절차의 구현을 만들어 보겠습니다.

절차 TForm1.bomb();
만약에 방법.Text= "" 다음 방법.Text:= "1";
ip.Text = ""이면 ip.Text:= "127.0.0.1";(IP 주소가 지정되지 않은 경우 다음 주소로 보냅니다. 로컬 컴퓨터}
WinExec(PChar("net send " + ip.Text + """ + txt.Text + """), 0);//문자 보내

이 절차에서는 필수 필드가 모두 채워졌는지 확인합니다. 메시지 텍스트가 없으면 "!" 기호를 설정합니다. IP 주소가 지정되지 않은 경우 주소 127.0.0.1을 사용하여 로컬 컴퓨터에 메시지를 보냅니다. 메시지 수가 지정되지 않은 경우 하나의 메시지를 보냅니다. 메시지는 다음 구문을 포함하는 표준 net send 명령을 사용하여 전송됩니다.

net은 IP 주소 메시지를 보냅니다.

이제 OnTimer 이벤트를 처리해 보겠습니다.

h: HWND;//창 ID를 저장합니다.
안전하지 않은 경우. 그런 다음 확인하십시오.//체크박스가 체크되지 않은 경우
타이머1.활성화:= 거짓;//모니터링 비활성화
안전하다면. 그런 다음 확인하세요.//체크박스가 체크된 경우
//메시지 창 찾기
h:= FindWindow(nil, "메시지 서비스");//발견된 모든 창을 닫습니다.
만약 h<>

메시지 수신 비활성화 확인란을 선택하면 제목이 메시지임을 나타내는 창 모니터링을 시작하고 발견된 모든 창을 닫습니다. 확인란을 선택하지 않으면 모니터링이 비활성화됩니다.

이 두 모드 사이를 전환하려면 secure.OnClick 이벤트 핸들러를 생성해야 합니다.

안전하다면. 그런 다음 확인하세요.//체크박스가 체크된 경우...
Timer1.Enabled:= 참;//...모니터링 활성화

버튼을 눌렀을 때 보내다간단히 폭탄 절차를 호출하겠습니다.

사용자의 생활을 더욱 편리하게 하기 위해 키를 눌러도 메시지가 전송되도록 하겠습니다. 텍스트 입력 필드에 이렇게 하려면 각 필드에 대해 OnKeyPress 이벤트 처리기를 만들어야 합니다. 이 핸들러의 코드는 ip 필드용이며, txt 및 How 필드에 할당할 수 있습니다.

열쇠라면= #13 그럼//키를 눌렀을 경우
폭탄;//문자 보내

전체 모듈 소스 코드

로컬 네트워크를 통해 메시지를 보내는 프로그램 모듈의 전체 코드는 목록 15.1에 나와 있습니다.

목록 15.1. 로컬 네트워크를 통해 메시지를 보내는 프로그램 모듈

Windows, 메시지, SysUtils, 변형, 클래스, 그래픽, 컨트롤, 양식, 대화 상자, StdCtrls, ExtCtrls;

절차 Timer1Timer(Sender: TObject);
절차 secureClick(보내는 사람: TObject);
절차 ipKeyPress(Sender: TObject; var Key: Char);
절차 txtKeyPress(Sender: TObject; var Key: Char);
절차 방법KeyPress(Sender: TObject; var Key: Char);
절차 Button1Click(보내는 사람: TObject);


//비어 있는지 확인 문자 메세지
txt.Text = ""이면 txt.Text:= "!";
//수량이 지정되지 않은 경우 하나의 메시지를 보냅니다.
if 방법.Text= ""이면 방법.Text:= "1";
ip.Text = ""이면 ip.Text:= "127.0.0.1"; (IP 주소가 지정되지 않은 경우 로컬 컴퓨터로 전송됩니다)
//지정된 수의 메시지를 보냅니다.
i:=1에서 StrToInt(how.Text)로 수행
WinExec(PChar("net send " + ip.Text + """ + txt.Text + """), 0); //문자 보내

절차 TForm1.Timer1Timer(Sender: TObject);
h: HWND; //창 ID를 저장합니다.
안전하지 않은 경우 Checked then //체크박스가 선택되어 있지 않은 경우
타이머1.활성화:= 거짓; //모니터링 비활성화
if secure.Checked then //체크박스가 선택된 경우
//메시지 창 찾기
h:= FindWindow(nil, "메시지 서비스"); //발견된 모든 창을 닫습니다.
만약 h<>0 다음 PostMessage(h, WM_QUIT, 0, 0);

절차 TForm1.secureClick(Sender: TObject);
if secure.Checked then //체크박스가 선택된 경우...
Timer1.Enabled:= 참; //...모니터링 활성화

절차 TForm1.ipKeyPress(Sender: TObject; var Key: Char);
if key = #13 then //키를 누른 경우
폭탄; //문자 보내

절차 TForm1.Button1Click(Sender: TObject);

⊚ 논의된 모든 프로젝트 파일과 프로그램의 실행 파일은 책과 함께 제공되는 CD의 Chapter 15 폴더에 있습니다.

메시지 보내기

게다가 윈도우 시스템메시지를 다양한 창으로 보내면 응용 프로그램 자체도 자체 창과 컨트롤 간에 메시지를 교환해야 할 수도 있습니다. 메시지를 보내는 방법에는 PerForm() 메서드(Windows API와 독립적으로 작동), Win32 API 함수 SendMessage() 및 PostMessage() 등 여러 가지가 있습니다.

TControl 클래스의 모든 하위 항목에 포함된 PerForm() 메서드는 다음과 같습니다.

함수 TControl.Perform(Msg: Cardinal; WParam, LParam: Longint): Longint;

폼이나 컨트롤에 메시지를 보내려면 다음 구문을 사용하십시오.

RetVal:= ControlName.PerForm(MessageID, wParam, lParam);

PerForm()이 호출되면 메시지가 처리될 때까지 제어가 호출 프로그램으로 반환되지 않습니다. 이 메서드는 Windows API 메시징 시스템을 거치지 않고 메시지를 전달합니다.

모듈에 선언된 API 함수 SendMessage() 및 PostMessage() 다음 윈도우방법:

함수 SendMessage(hWnd: HWND; Msg: UINT; wParam: WPARAM;

lParam: LPARAM): LRESULT; 표준 호출;

함수 PostMessage(hWnd: HWND; Msg: UINT;

wParam: WPARAM; lParam: LPARAM): BOOL; 표준 호출;

hWnd – 메시지 수신자 창 핸들; Msg – 메시지 식별자; wParam 및 lParam – 추가 데이터.

PerForm() 메서드와 마찬가지로 SendMessage() 함수는 창 프로시저에 직접 메시지를 보내고 처리될 때까지 기다리는 반면 PostMessage() 함수는 메시지 대기열에 메시지를 배치하고 호출한 프로그램에 제어를 반환합니다. 처리 결과를 기다리지 않고 바로 처리됩니다.

SendMessage() 함수는 메시지 처리 결과 얻은 값을 반환합니다. PostMessage() 함수 - 메시지가 메시지 대기열에 성공적으로 게시되었는지 여부를 나타내는 값을 반환합니다.

사용자 메시지

애플리케이션을 개발할 때 애플리케이션이 특정 작업을 수행하기 위해 자체 또는 다른 애플리케이션에 특수 메시지를 보내야 하는 상황이 있을 수 있습니다. 사용자가 생성한 메시지의 경우 Windows는 WM_USER에서 $7FFF까지 값을 예약합니다.

맞춤 메시지의 예:

TestMsg = WM_USER + 100; // 메시지 ID

TForm1 = 클래스(TForm)

// 메시지 처리 방법:

절차 MyMessage(var Msg: TMessage); 메시지 TestMsg;

절차 TForm1.MyMessage(var Msg: TMessage);

ShowMessage("TestMsg 메시지 실행 중");

메시지결과:= 1; // 결과 반환

양식에 메시지를 보내는 예:

Form1.PerForm(TestMsg, 0, 0) = 1이면

SendMessage(Form1.Handle, TestMsg, 0, 0) = 1이면

ShowMessage("메시지가 성공적으로 처리되었습니다.");

if PostMessage(Form1.Handle, TestMsg, 0, 0) 그러면

ShowMessage("메시지가 메시지 대기열에 추가되었습니다.");

델파이 이벤트

이벤트는 프로그램이 실행되는 동안 발생하는 일입니다. 델파이 언어의 관점에서 볼 때 이벤트는 절차적 유형의 속성이고 해당 값은 일부 메서드에 대한 포인터입니다. 이러한 속성에 값을 할당한다는 것은 이벤트가 발생할 때 실행될 메서드의 주소를 지정한다는 의미입니다. 이러한 메소드를 이벤트 핸들러라고 합니다.

이벤트를 사용하면 하위 클래스를 만들지 않고도 기존 클래스에 새 기능을 추가할 수 있습니다.

이벤트 속성은 "On"이라는 단어로 시작하고 그 뒤에 이벤트 이름이 옵니다.

메시지와 이벤트의 관계

Delphi는 Windows 메시지(적어도 그 중 일부)와 상호 작용하기 위한 인터페이스를 제공합니다. 많은 VCL 구성 요소 이벤트는 메시지와 직접적으로 관련되어 있습니다. 윈도우 유형 WM_XXX.

Delphi의 메시지 처리 순서
모든 Delphi 클래스에는 메시지 처리기라는 메시지 처리 메커니즘이 내장되어 있습니다. 클래스는 메시지를 수신하고 수신된 메시지에 따라 정의된 메서드 집합 중 하나를 호출합니다. 해당 메서드가 정의되지 않은 경우 기본 핸들러가 호출됩니다. 좀 더 자세히 설명하면 이 메커니즘은 다음과 같이 작동합니다.

메시지가 수신되면 VCL 메시지 시스템은 이를 처리하기 위해 많은 사전 작업을 수행합니다.

위에서 언급한 것처럼 메시지는 처음에 TApplication.ProcessMessage 메서드에 의해 처리되며, 이 메서드는 기본 메시지 루프의 대기열에서 메시지를 선택합니다. 동시에 FOnMessage 필드의 내용을 확인하고(실제로는 OnMessage 이벤트에 대한 핸들러가 있는지 확인합니다) 비어 있지 않으면 이 이벤트에 대한 핸들러를 호출합니다. 비어 있으면(Nil) API 함수 DispatchMessage(Msg)를 호출합니다. 메시지를 보낼 때는 이런 일이 발생하지 않습니다.

OnMessage 이벤트 핸들러가 정의되지 않은 경우 DispatchMessage API 함수가 호출되어 수신된 메시지를 처리하고 메시지를 기본 창 프로시저로 전달합니다.

메시지가 구성 요소의 기본 창에 도착한 후의 메시지 처리 주기를 고려해 보겠습니다. 메시지 처리 순서는 다음 그림에 나와 있습니다.

메시지가 MainWndProc, WndProc, Dispatch, DefaultHandler로 전송되는 것을 볼 수 있습니다.

Delphi는 주요 비가상 방법을 제공합니다. MainWndProc(Var Message: TMessage) 각 구성 요소 창에 대해. 여기에는 Windows의 메시지 구조를 WindowProc 속성에 정의된 가상 메서드로 전달하는 예외 처리 블록이 포함되어 있습니다. 그러나 이 메서드는 애플리케이션의 HandleException 메서드를 호출하여 메시지 처리 중에 발생하는 모든 예외를 처리합니다. 이 시점부터 프로그램 논리에 필요한 경우 메시지의 특수 처리를 제공할 수 있습니다. 일반적으로 이 시점에서 표준 VCL 처리가 발생하지 않도록 처리가 수정됩니다.

기본적으로 개체의 WindowProc 속성 값은 WndProc 가상 메서드의 주소로 초기화됩니다. 다음으로, TWindowHook 유형의 등록된 메시지 인터셉터가 없는 경우 WndProc는 가상 메서드 TObject.Dispatch를 호출합니다. 이 메서드는 들어오는 메시지 구조의 Msg 필드를 사용하여 메시지가 이 개체에 대한 메시지 처리기 목록에 있는지 여부를 결정합니다. 개체가 메시지를 처리하지 않으면 상위 메시지 처리기 목록이 검사됩니다. 이러한 메서드가 결국 발견되면 해당 메서드가 호출되고, 그렇지 않으면 DefaultHandler 가상 메서드가 호출됩니다.

마지막으로 메시지는 적절한 처리 절차에 도달하여 해당 메시지에 대한 처리가 수행됩니다. 사용하여 예어상속된 것은 조상 처리를 위해 추가로 전송됩니다. 그런 다음 메시지는 최종 메시지 처리를 수행하고 이를 표준 Windows 처리를 위해 DefWindowProc(DefMDIProc) 프로시저에 전달하는 DefaultHandler 메서드로 이동합니다.

Delphi 구성요소로 메시지 처리하기
따라서, 간단한 설명메시지 처리 순서는 다음과 같습니다. 모든 메시지는 처음에 WindowProc 속성에 주소가 지정된 메서드를 통해 전달됩니다. 기본적으로 이는 WndProc 메서드입니다. 그 후에는 각자의 메시지 방법에 따라 분리되어 전송됩니다. 마지막에는 이전에 처리되지 않았거나 상속된 처리기(Inherited)가 처리기에서 호출되는 경우 DefaultHandler 메서드에서 다시 수렴됩니다. 그러므로, 델파이 구성요소메시지 처리에는 다음과 같은 옵션이 있습니다.
a) 메시지 핸들러가 메시지를 보기 전. 이 경우 WindowProc 속성의 메서드 주소를 바꾸거나 TControl.WndProc 메서드를 바꿔야 합니다.
WindowProc 속성은 다음과 같이 선언됩니다.

투레 TWnd방법= 절차(Var 메시지: TMessage) 객체의;
재산 WindowProc: TWndMethod;

실제로 WindowProc 속성을 사용하면 TWndMethod 유형의 메서드를 생성하고 임시로 원래 메서드를 생성된 메서드로 바꿀 수 있지만 WindowProc 속성의 메서드 주소는 저장되지 않으므로 먼저 해당 메서드의 주소를 저장해야 합니다. 나중에 복원할 수 있도록 원래 WndProc 메서드를 사용합니다.

OldWndProc: TWnd메소드;
절차 NewWndProc(var 메시지: TMessage);
절차 TForm1.NewWndProc(var 메시지: TMessage);
var Ch: 문자;
시작하다
message.Msg= WM_MOUSEMOVE이면 시작합니다.
Edit1.Text:='x='+inttostr(message.LParamLo)+', y='+inttostr(message.LParamHi);

else WndProc(메시지);
끝;

절차 TForm1.FormCreate(Sender: TObject);
시작하다
OldWndProc:=WindowProc;
끝;

절차 TForm1.CheckBox1Click(Sender: TObject);
시작하다
CheckBox1.Checked이면 WindowProc:= NewWndProc
그렇지 않으면 WindowProc:= OldWndProc;
끝;

b) 해당 메시지 메소드 내부.
또 다른 비슷한 예를 들어 보겠습니다.
구성요소에 전송된 메시지를 사용하여 WMPAINT를 다시 그립니다.

TForml 클래스에서는 이를 재정의할 목적으로 이 메서드를 선언하고 재정의된 메시지 메서드의 구현을 제시합니다.

물론 TForml=클래스(TForm)
… // 기타 필요한 모든 선언
보호됨
절차 WWMPaint(Var Msg: TWMPaint); 메시지 WM_PAINT; 끝;
절차 TForml.WMPaint(Var Msg: TWMPaint); 시작하다
If CheckBox1.Checked Then ShowMessage('O6pa6ot 메시지!');
상속됨;
끝;

특정 메시지 처리기를 재정의하는 경우 항상 Inherited를 호출하여 Windows에 필요한 기본 메시지 처리를 수행하는 것이 좋습니다.

c) 메시지에 해당하는 각 메소드를 실행한 후 메시지를 확인합니다.

이 경우 DefaultHandler를 재정의해야 합니다.

절차 DefaultHandler(var Message); 우세하다;
절차 TForm1.DefaultHandler(var Message);
var i:정수;
시작하다
Cardinal(Message)=WM_defh이면
for i:= 0 ~ 10 시작하세요
삑 하는 소리;
수면(100);

또 다른
상속됨;
끝;

절차 TForm1.Button5Click(Sender: TObject);
시작하다
SendMessage(핸들,WM_defh,0,0);
끝;

메시지와 이벤트의 관계
많은 VCL Delphi 이벤트는 Windows 메시지와 직접적으로 관련되어 있습니다. Delphi 도움말 시스템에는 이러한 일치 항목이 나열되어 있습니다. 이는 표 1에 제시되어 있습니다.

1 번 테이블

VCL 이벤트윈도우 메시지VCL 이벤트윈도우 메시지
켜기활성화WM_ACTIVATEOnKeyPressWM_CHAR
온클릭WM_LBUTTONDOWNOnKeyUpWM_KEYUP
생성 시WM_CREATE온페인트WM_PAINT
OnDblClickWM_LBUTTONDBLCLK크기 조정 시WM_SIZE
OnKeyDownWM_KEYDOWN온타이머WM_TIMER

미리 정의된 이벤트가 있는 경우 메시지 처리기를 생성하면 안 됩니다. 이러한 경우에는 제한 사항이 적기 때문에 이벤트 처리를 사용하는 것이 좋습니다.

이런 곳

IdTCPClient1.Host:= "127.0.0.1"; IdTCPClient1.Connect;// 연결됨 IdTCPClient1.Socket.WriteLn("command"); // 명령 전송 및 줄 바꿈 // 응답을 기다리고 연결을 닫습니다. txtResults.Lines.Append(IdTCPClient1.Socket.ReadLn); IdTCPClient1.Disconnect;

이 경우 명령은 줄 바꿈이 있는 텍스트일 뿐입니다. 이렇게 하면 상대방으로부터 명령을 받는 것이 훨씬 쉬워집니다(ReadLn만 해당). 일반적인 경우에는 프로토콜을 생각해 내야 합니다(또는 기성품을 사용해야 합니다).

그 위에는 클라이언트가 있었습니다. 그리고 이제 서버입니다. 서버를 사용하면 모든 것이 조금 더 복잡해집니다. 서버가 하나의 클라이언트가 아닌 여러 클라이언트에 서비스를 제공하는 것이 정상이라는 것은 분명합니다. 그리고 이에 대한 몇 가지 "계획"이 있습니다.

    클래식 - 하나의 클라이언트 - 하나의 스레드. 이 구성표는 코딩하기 쉽고 직관적입니다. 이는 코어 전반에 걸쳐 잘 병렬화됩니다. 단점은 일반적으로 많은 스레드를 생성하는 것이 매우 어렵고 이로 인해 클라이언트 수가 제한된다는 것입니다. 32비트 프로그램의 경우 상한은 프로세스당 약 1500개(1500개) 스레드입니다. 그러나 이 경우 전환에 드는 간접비로 인해 전체 비율이 "먹어버릴" 수 있습니다. 이것이 인디에서 사용되는 방식입니다.

    두 번째 고전적인 것은 하나의 스레드에 있는 모든 클라이언트입니다. 이 체계는 코딩하기가 더 복잡한 경우가 많지만 올바른 접근 방식을 사용하면 사실상 커널에 로드가 전혀 없는 상태에서 20~30,000명의 "느린 사용자"를 유지할 수 있습니다. 이 방식의 가장 큰 장점은 뮤텍스 및 기타 동기화 프리미티브 없이 작업을 수행할 수 있다는 것입니다. 이 체계는 Qt의 네트워크 작업을 위해 NodeJS 및 표준 클래스에서 사용됩니다.

    혼합. 이 경우 여러 스레드가 생성되며 각 스레드는 특정 수의 클라이언트에 서비스를 제공합니다. 코딩하기가 가장 어렵지만 하드웨어 리소스를 최대한 활용할 수 있습니다.

인디에서는 어떻게 이루어지나요? Indy TCP 서버는 각 연결에 대해 별도의 스레드(TThread)를 생성하고 추가 작업클라이언트가 그 안으로 걸어들어가는 것과 함께 말이죠. Indy는 이를 훌륭하게 숨겨 사용자가 IdTCPServer.onExecute 메서드만 구현하도록 합니다. 하지만 위에서 말했듯이 이 방법은 별도의 스레드에서 시작되며 각 클라이언트마다 개인적입니다. 이는 다음을 의미합니다.

  • 이 방법에서는 sleep을 호출할 수 있으며 단 하나의 클라이언트만 대기합니다. 다른 모든 기능은 작동합니다(단, 버튼 클릭 핸들러에서 sleep을 호출하면 결과가 알려짐).
    • 동기화 프리미티브를 통해서만 전역 변수에 액세스하는 것이 좋습니다.
    • GUI 요소에 신중하고 정확하게 액세스해야 합니다. 직접 수행하지 않는 것이 좋습니다(일부 구성 요소는 다른 스레드에서 액세스할 수 있지만 문서를 주의 깊게 읽어야 합니다).
    • 차단을 통해 다른 클라이언트에 액세스해야 합니다(두 스레드가 동일한 사용자에게 쓰려고 하면 아무 소용이 없기 때문입니다).

아주 간단한 예를 살펴보겠습니다. 우리는 모든 클라이언트 요청에 대해 친절하게 응답하고 연결을 닫습니다(일종의 에코 서버).

프로시저 TForm1.IdTCPServer1Execute(AContext: TIdContext); var strText: 문자열; start //클라이언트로부터 문자열 수신 strText:= AContext.Connection.Socket.ReadLn; //응답 AContext.Connection.Socket.WriteLn(strText); //사용자 AContext.Connection.Disconnect와의 연결을 닫습니다. 끝;

AContext는 모든 내용을 포함하는 특수 객체입니다. 필요한 정보클라이언트에 대해. idTcpServer 자체에는 이러한 컨텍스트 목록이 포함되어 있으며 액세스할 수 있습니다. 좀 더 복잡한 방송을 생각해 봅시다. 즉, 모든 사람에게 하나의 메시지를 보냅니다.

Var 클라이언트: TList; i:정수; 시작 // 바보 방지 :) 할당되지 않은 경우(IdTCPServer1.Contexts) 종료합니다. // 클라이언트 목록을 가져와서 잠급니다. Clients:=IdTCPServer1.Contexts.LockList; try for i:= 0 to Clients.Count-1 do try //LBuffer는 TBytes 유형이며 전송을 위해 준비된 데이터를 포함하지만 //WriteLn도 사용할 수 있습니다. TIdContext(클라이언트[i]).Connection.IOHandler.Write(LBuffer); 제외 // 여기에 논리를 추가해야 합니다. 클라이언트는 프로세스가 종료되는 동안 연결이 끊어질 수 있습니다. 마지막으로 // 중요합니다! 목록을 잠금 해제해야 합니다. 그렇지 않으면 다른 메소드가 더 이상 진행할 수 없습니다. Contexts.LockList IdTCPServer1.Contexts.UnlockList; 끝; 끝;

인디에는 String과 TIdBytes를 서로 변환하기 위한 BytesToString() 및 ToBytes()가 포함되어 있습니다.

다른 사람이 수정할 수 없도록 목록이 잠겨 있습니다. 그렇지 않으면 주기 자체가 훨씬 더 복잡해집니다. 그리고 가장 중요한 것은 잠금을 해제하는 것을 잊지 마세요!

마지막 질문이 하나 남았습니다. 특정 클라이언트에게 메시지를 보내는 방법. 이렇게 하려면 연결을 식별하는 방법을 배워야 합니다. 이는 여러 가지 방법으로 수행할 수 있습니다. IP/포트를 살펴보십시오. 그러나 더 좋은 것이 있습니다. IdContext(보다 정확하게는 해당 조상 idTask)에는 TObject 유형의 Data 속성이 있습니다. 여기에 개체를 작성하고 필요한 모든 데이터를 저장할 수 있습니다. 일반적인 사용 사례는 다음과 같습니다. 클라이언트가 방금 연결한 경우 이 필드는 비어 있습니다. 이름-비밀번호 확인을 통과하면 객체(자체)를 생성하고 거기에 이름을 저장한 후 Data 속성에 씁니다. 그런 다음 연결된 클라이언트를 반복해야 할 때 간단히 읽으면 됩니다. 물론, 사용자가 수천 명이라면 매번 모든 사용자를 조회하는 것은 비용이 많이 들 것입니다. 그러나 이를 보다 최적으로 수행하는 방법은 또 다른 대규모 기사의 주제입니다.

Delphi를 사용하면 메일을 보내고 받는 것이 매우 간단합니다. 메일을 보내려면 Delphi 컴포넌트 팔레트의 Indy Clients 페이지에 있는 idSMTP 컴포넌트가 필요합니다.

이 구성 요소는 전송에 필요한 모든 것을 구현합니다. 이메일명령과 문자 텍스트가 전송되는 포트 25를 사용하는 SMTP 프로토콜(Simple Mail Transfer Protocol)을 통해. 이메일을 보내는 단계는 다음과 같습니다.

1) 포트 25에서 SMTP 서버에 연결
2) 편지의 본문을 준비하고 편지의 발신자와 수신자를 식별합니다.
3) SMTP 서버에 편지를 보냅니다.

idSMTP 구성 요소를 양식에 배치한 후 구성해 보겠습니다. Port 속성을 25로 설정하여 개체 검사기에서 포트를 구성하거나 프로그램 코드에서 동일한 작업을 수행할 수 있습니다.

IdSMTP1.포트:=25;

서버에 연결

메일을 보낼 SMTP 서버에 연결하려면 해당 URL을 지정해야 하며, mail.ru 서버의 경우 다음과 같이 수행됩니다.

IdSMTP1.Host:= 'smtp.mail.ru';

서버에 대한 연결은 Connect 메서드를 사용하여 이루어집니다.


프로시저 Connect(const ATimeout: Integer); 우세하다;

여기서 ATimeout은 연결 설정 시도가 종료된 후 SMTP 서버의 응답을 기다리는 최대 시간(밀리초)을 지정하는 선택적 매개변수입니다.

예를 들어,

IdSMTP1.Connect(5000);

서버에 연결할 때 인증이 필요한 경우 AuthenticationType 속성의 값을 atLogin으로 설정해야 하며, 개체 검사기에서 사용자 이름 속성(예: 사용자 이름)도 정의해야 합니다. 사서함 [이메일 보호됨]- delphi) 및 Password(사서함 비밀번호) 또는 프로그래밍 방식으로 동일한 작업을 수행합니다.

IdSMTP1.AuthenticationType:=atLogin;
IdSMTP1.Username:='델파이';
IdSMTP1.Password:='뭔가';

IdSMTP1.AuthenticationType:=atNone;

Connect 메서드를 사용한 후에는 연결에 성공하면 True로 설정되는 논리적 속성인 Connected를 분석해야 합니다. 그런 다음 Send 메서드를 사용하여 메시지를 보낼 수 있습니다.

Connected=True이면 IdSMTP1.Send(Msg);

문자 구조

Send 메서드는 TIdMessage 유형의 구조인 메시지 본문을 보냅니다.

메시지 구조는 Indy Misc 컴포넌트 팔레트에 있는 별도의 TIdMessage 컴포넌트에 의해 Delphi에서 구현되며 다음과 같습니다.

TidMessage TIdMessage 구조는 다음과 같이 정의됩니다.

메시지 제목으로 모든 것이 명확하다고 생각합니다. 재산

편지가 전달되는 전자 계좌의 이름은 구체적으로 결정됩니다. 이름은 "," 형식의 구분 기호, 즉 쉼표로 구분하여 지정해야 합니다. 예를 들어:

예를 들어,

예를 들어,

Text 속성에는 두 속성의 정보가 모두 포함되어 있습니다. 메시지 본문은 TStrings 유형의 객체입니다.

여기서 Collection은 TIdMessageParts 클래스의 객체입니다. 이메일.
TFileName 유형의 상수 AFileName - 파일의 올바른 경로를 나타내는 일반 텍스트 문자열입니다(예: "C:file.zip"). 기본값은 ''입니다.

따라서 다음과 같은 줄로 예제를 계속합니다.

공유하다