23.02.28 22:20 작성
·
529
0
안녕하세요, listener, session 코드간 차이점에 대해서 질문이 있습니다.
1, listener에서는 OnRecvCompleted()와같은 메서드에서 socketerror가 발생했을 때, disconnect를 하지 않았는데, session에서는 왜 disconnect를 하는 건가요?
2.listener 에서는 registerRecv() 와같은 함수를 OnRecvCompleted의 if, else와 상관없이 실행한거같은데, 왜 session에서는 if(args.Bytes.Transferred > 0 && ~~~) 을 만족해야 OnRecvCompleted를 실행하는건가요?
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
namespace ServerCore
{
class Session
{
Socket _socket;
public void init(Socket socket)
{
_socket = socket;
SocketAsyncEventArgs recvArgs = new SocketAsyncEventArgs();
recvArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnRecvCompleted);
//userTocken으로 추가적인 정보를 아무거나넘겨줄 수 있다(object를 받기 때문)
recvArgs.SetBuffer(new byte[1024],0,1024);
RegisterRecv(recvArgs);
}
void RegisterRecv(SocketAsyncEventArgs args)
{
args.AcceptSocket = null;
bool pending = _socket.ReceiveAsync(args);
//바로 성공했으면
if(pending == false)
{
OnRecvCompleted(null, args);
}
}
void OnRecvCompleted(object obj, SocketAsyncEventArgs args)
{
//BytesTransferred == 몇바이트 받았는지
if (args.BytesTransferred>0 && args.SocketError == SocketError.Success)
{
try
{
string recvData = Encoding.UTF8.GetString(args.Buffer, args.Offset, args.BytesTransferred);
Console.WriteLine($"[from client] : {recvData}");
RegisterRecv(args);
}
catch(Exception e)
{
Console.WriteLine($"onrecvcompleted failed {e}");
}
}
else
{
//TODO Disconnect
}
}
}
}
답변 3
0
2023. 03. 04. 14:45
감사합니다. 그런데,
listener는 accept를 실패했더라도 다른 client들을 계속 기다려야 하니까 if, else절 상관없이 받는 것이라고 이해했긴 했는데, (맞는진 모르겠습니다)
session은 recv를 한번의 stream들만 받는거니까 계속해서 args.BytesTransferred > 0 인 경우에만 계속해서
RegisterRecv(args); 로 낚싯대를 놓는걸로 이해했는데 맞을까요?
0
2023. 03. 02. 00:05
Listener는 문지기의 역할이고,
Session은 들어온 다음에 상대방 클라를 대표하는 일종의 대리인입니다.
따라서 세션이 끊기면 킥해주는 것이지만
Listener는 서버에서 문지기 역할을 담당하기에
우리가 내보낼 일이 없습니다.
2023. 03. 04. 14:54
네 그렇습니다.
accept는 딱히 실패할 이유가 없고, 찰나의 순간 연결이 끊긴다면
어차피 Recv 0로 감지가 가능합니다.
Recv했는데 0 바이트를 수신했다는 것은,
(처음 수신 버퍼 사이즈를 0바이트로 일부러 세팅하는 0byte Recv 등의 기법이 아니라면)무조건 상대방 연결이 끊길 때 발생합니다.