C#에서 비동기 소켓 메서드를 사용하는 올바른 방법에 대해 혼란스러워합니다. 나는이 두 기사를 참조하여 내 질문을한다 : MSDN article on asynchronous client sockets과 devarticles.com article on socket programming.C#의 비동기 소켓
내 질문에 대한 답변은 BeginReceive()
입니다. MSDN 문서는 수신 데이터를 처리하기 위해이 두 가지 기능을 사용하십시오 devarticles.com 튜토리얼이 BeginReceive
방법의 마지막 매개 변수에 대한 null
를 전달하는 동안
private static void Receive(Socket client)
{
try
{
// Create the state object.
StateObject state = new StateObject();
state.workSocket = client;
// Begin receiving the data from the remote device.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ReceiveCallback(IAsyncResult ar)
{
try
{
// Retrieve the state object and the client socket
// from the asynchronous state object.
StateObject state = (StateObject) ar.AsyncState;
Socket client = state.workSocket;
// Read data from the remote device.
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead));
// Get the rest of the data.
client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,
new AsyncCallback(ReceiveCallback), state);
}
else
{
// All the data has arrived; put it in response.
if (state.sb.Length > 1)
{
response = state.sb.ToString();
}
// Signal that all bytes have been received.
receiveDone.Set();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
을하고, 마지막 매개 변수는 우리가 '할 때 유용하다는 것을 설명하기 위해 계속 여러 개의 소켓을 다루고 있습니다. 이제 내 질문은 :
우리는 단지 하나의 소켓에 작업하는 경우
BeginReceive
방법에 상태를 전달하는 점은 무엇입니까? 클래스 필드 사용을 피하는 것입니까? 그것을하는 데는 작은 점이있는 것처럼 보이지만, 아마도 나는 뭔가를 놓치고 있습니다.여러 소켓을 처리 할 때 상태 매개 변수가 어떻게 도움이 될 수 있습니까?
client.BeginReceive(...)
이라면client
소켓에서 모든 데이터를 읽을 수 있습니까? devarticles.com 튜토리얼은이 호출에 같은 소리한다 :m_asynResult = m_socClient.BeginReceive (theSocPkt.dataBuffer,0,theSocPkt.dataBuffer.Length, SocketFlags.None,pfnCallBack,theSocPkt);
데이터 대신 m_socClient
소켓에서의, theSocPkt.thisSocket
소켓에서 읽을 수 있습니다. 그들의 예에서 두 개는 동일하고 동일하지만, 그렇지 않은 경우 어떻게됩니까?
필자는 마지막 인수가 유용하거나 적어도 여러 소켓에서 어떻게 도움이되는지 실제로 알지 못합니다. 소켓이 여러 개있는 경우 각각 BeginReceive
으로 전화해야합니다. 맞습니까?
그리고 프로그래머는 상태 객체에 포함 된 소켓이 'BeginReceive'가 호출 된 소켓 객체와 똑같은지 확인해야합니다. 맞습니까? 나는 그들이 다른지, 그것이 오류를 일으킬 것 같아요. – IVlad
필수 사항은 아닙니다. .NET을 사용하면 여러 통화가 동시에 발생하더라도 상태를 안정적으로 전송할 수 있습니다. 일반 함수를 호출 할 때받은 매개 변수가 호출하는 데 사용 된 호출자와 동일한 객체인지 점검 할 필요가 없습니다. 그렇게했다면 매개 변수를 전달할 수 있다는 것은 실용적인 가치가 없습니다. 원본 개체를 비교하기 위해서는 원본 개체를 참조해야하기 때문입니다. –
그건 내가 의미하는 것이 아닙니다. 예를 들어 이것을'BeginReceive' 콜백 함수 안에'Socket client = state.workSocket; 'state.workSocket = B'을 수행 한 후'StateObject state'를 전달하는'BeginReceive '라는 소켓'A'를 생각해보십시오. 이것은'A == B' 인 경우에만 유효합니다. 맞습니까? 나는 모든 예제가 receive 메소드를 호출하는 데 사용 된 상태로 동일한 소켓을 전달하기 때문에 약간 혼란 스럽다. 그러나 둘 다 똑같이 명시해야한다고 명시하지 않았다. 나는 그들이해야한다고 생각하지만, 이것이 사실인지 확인하고 싶습니다. – IVlad