delphi를 시작한지 1달 정도 되었습니다.
다름이 아니오라 소켓통신은 동기식과 비동기식으로 나뉜다고 들었습니다.
동기식 통신을 하기 위해서 우선 클라이언트에서 메시지를 '##보낼분자열길이@@보낼문자열' 으로 서버쪽에 보내서 서버쪽에서는 클라이언트쪽에서 보낸 메시지를 받아 그값이 정상적으로 들어왔나를 체크해서 만약 들어오지 않았을 경우는 해당 클라이언트에세 메시지가 정상적으로 도착하지 않았음을 알리고 해당 메시지를 다시 보내라는 것을 구현하기 위해서는 어떻게 해야할지 잘 모르겠습니다.
아시는분 계시면 답변 좀 부탁드리겠습니다.
--------Client에서 보내는 부분
procedure TForm1.memSendKeyPress(Sender: TObject; var Key: Char);
var
SendMsg : string;
i: Integer;
begin
if key = #13 then
begin
if ClientSocket1.Active then
begin
key := #0;
for i := 0 to 99 do
begin
SendMsg := '##'+ format('%10d', [length(Form1.memSend.Text)]) + '@@';
SendMsg := SendMsg + Form1.memSend.Text;
end;
ClientSocket1.Socket.SendText(SendMsg);
form1.memSend.Lines.Clear;
form1.memSend.SetFocus;
form1.memSend.SelStart := 0;
end
else
begin
memReceive.Lines.Add('Cannot send message when disconnected!');
form1.memSend.Lines.Clear;
form1.memSend.SetFocus;
form1.memSend.SelStart := 0;
end;
end;
end;
----Server에서 받는 부분
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
ReceiveMsg, body_data : string;
st, en, i, j, body_length : integer;
begin
ReceiveMsg := Socket.ReceiveText;
body_data := ReceiveMsg;
st := pos('##', ReceiveMsg);
en := pos('@@', ReceiveMsg);
if (st > 0 ) and (en > 0) then
begin
// ##0000000000@@
body_length := StrToInt(copy(ReceiveMsg, st + 2, 10));
body_data := copy(ReceiveMsg, en+2, 100000);
end;
if length(body_data) = body_length then
begin
ReceiveMsg := body_data;
Socket.SendText('##'+format('%10d', [length(ReceiveMsg)])+'@@'+ReceiveMsg);
Form1.memReceive.Lines.Add('##'+format('%10d', [length(ReceiveMsg)])+'@@'+ReceiveMsg);
end;
if length(body_data) > body_length then
begin
Form1.memReceive.Lines.Add('!ERROR');
end;
end;
TCP를 이용하시는 것이라면, 잘못된 데이터의 전송에 대한 고려를 하지 않으셔도 됩니다. 지금은 전송 기술도 많이 발달되어 있고, TCP 자체가 오류에 의해서는 자동으로 재전송등을 내부적으로 처리해 주는 프로토콜이기 때문입니다. UDP로 작성을 하신다면 모르겠지만 말이죠. ^^;
동기식 소켓을 따로 구현하실 필요는 없구요. 이미 유용한 컴포넌트들이 많이 있습니다. 뭐 요새는 인디를 많이 사용하더군요. 별로 추천하고 싶지는 않지만...(너무 무거운 패키지인지라...)
동기식으로 처리를 한다면, 꼭 쓰레드로 처리를 하셔야 합니다. 뭐 꼭은 아니지만, 서버에서 데이터를 수신할 때까지 프로그램이 멈춰있어도 상관없다면 말이죠. ^^; 비동기식으로 처리를 한다면 상관없겠죠. 데이터를 수신하는 이벤트만 처리하면 되니까요.
아래의 코드를 보면, 클라이언트 측에서 100번 계속 데이터를 송신하고, 서버측에서 수신을 하는데, 클라이언트에서 100번 송신했다고 해서 서버측에서 100번 수신하지는 않습니다. 연속적으로 데이터를 보내는 경우, 내부 버퍼의 크기와 TCP 패킷의 크기에 따라서, 실제로 보내는 양보다 많게 갈 수가 있기 때문에, 아마도 실제로는 100번보다 적게 받게 될겁니다. 그렇다고 클라이언트에서 보낸 데이터를 잃는 것은 아니고, 100번에 보낸 데이터를 몇몇 개가 합쳐져서 더 적은 수의 패킷으로 날아오게 되죠. 이것 프로토콜을 설계한 사람들이 데이터를 좀더 효율적으로 보내기 위해서, 조금씩 많이 보내는 비효율적인 상황을 줄이기 위해서, 한 패킷이 최대 보낼 수 있는 양을 다 채워서 보내게끔 되어 있기 때문이지요.
그렇기 때문에, 아래와 같은 코딩은 잘 못된 것입니다. 아래와 같은 코딩을 적용하기 위해서는 내부적으로 버퍼를 유지하고 있는 다른 컴포넌트를 사용하셔야 합니다. 그런 컴포넌트중의 하나가 인디입니다. 대부분의 동기식 코딩(한줄 단위의 전송)에서 주로 인디를 사용하더군요. 내부적으로 버퍼를 처리해주니까, 프로그래머가 그 부분을 신경써 주지 않아도 되기 때문이죠. 이러한 인디에 대한 예는 많으니까, 한번 찾아보시구요.
인디를 사용하셔서 코딩하시면 쉽게 구현하실 수 있으리라 생각됩니다.
생각 나는대로 마구 적어서 틀린 내용이 있을 겁니다.
그런 부분은 애교로 봐주시고... 이만 허접한 답변을 접겠습니다. ^^;