블로그는 나의 힘!
[ Programing ]/Server2018. 10. 16. 17:20

Poll() 메소드


보통 Receive() 명령과 같은 블로킹 네트워크 함수를 실행하고자 한다면,

이 명령어를 실행하기 전에 소켓을 확인할 수 있는 기능이 있어야 한다.

 

소켓 메소드 Poll() 바로 이런한 기능을 수행한다.

이 메소드는 소켓 객체를 확인하여 네트워크 메소드 콜이 블록을 거는지, 또는 성공적으로 완료 했는지를 확인한다.

Poll() 메소드의 형태는 다음과 같이 간단하다.

 

bool Poll(int microseconds, SelectMode mode);

 

Poll() 메소드는 간단한 boolean 값을 반환하는데,

수행하고자 하는 행동이 블록을 걸지 않고 완료할 수 있으면, true를, 블록을 걸면 false를 반환하다.

 

int 파라미터는 Poll() 메소드가 특정 이벤트에 대해서 소켓을 주시하는 시간을 microseconds 단위로 나타낸 것이다.

SelectMode 파라미터는 주시해야 할 행동을 나타낸다.

SelectMode 클래스는 Poll() 메소드가 모니터링할 세 개의 가능한 이벤트들을 수치화한 것이다.

    namespace System.Net.Sockets
    {
        public enum SelectMode
        {
            SelectRead = 0,
            SelectWrite = 1,
            SelectError = 2
        }
    }

 

SelectRead

: SelectMode 클래스의 SelectRead 값을 사용할 경우, 다음과 같은 조건을 만족하면 Poll() 메소드가 true를 반환한다.

○ Accept() 메소드가 성공

○ 소켓에 읽어들일 데이터가 있을 때

○ 연결이 종료되었을 떄

 

SelectWrite

: SelectMode 클래스의 SelectWrite 값을 사용할 경우, 다음과 같은 조건을 만족하면 Poll() 메소드가 true를 반환한다.

○ Connect() 메소드가 성공했을 때

○ 소켓으로 데이터를 전송할 수 있을 때

 

SeletError

: SelectMode 클래스의 SelectError 값을 사용할 경우, 다음과 같은 조건을 만족하면 Poll() 메소드가 true를 반환한다.

○ Connect() 메소드가 실패했을 때

○ 대역 외 데이터가 있는데 소켓의 OutOfBandInline 속성이 설정되지 않았을 때

 

 

 

설정된 SelectMode 값에 대해서

Poll() 메소드가 반환하는 값을 참고하여 소켓에 블로킹 함수를 실행할지 여부를 판단할 수 있다.

 

result = sock.Poll(1000000, SelectMode.SelectRead);

 

소켓 객체 sock는 1백만 microsecond(1초) 동안 확인하여 소켓에 데이터가 있는지를 판단한다. 반환값이 true이면, Receive() 메소드는 블로킹 없이 완료할 수 있다는 뜻이다.

 

 

 

예제 )


using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

 

namespace TcpPollServer
{
    class TcpPollServer
    {
        static void Main(string[] args)
        {
            int recv;
            byte[] data = new byte[1024];
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050);

            Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

 

            newsock.Bind(ipep);
            newsock.Listen(10);


            Console.WriteLine("Waiting for a client...");


            bool result;
            int i = 0;


            while (true)
            {
                i++;


                Console.WriteLine("polling for accept#{0}...", i);


                result = newsock.Poll(1000000, SelectMode.SelectRead);
                if (result)
                {
                    break;
                }
            }


            Socket client = newsock.Accept();

            IPEndPoint newclient = (IPEndPoint)client.RemoteEndPoint;
            Console.WriteLine("Connected with {0} at port {1}", newclient.Address, newclient.Port);

 

 

 

 

            string welcome = "Welcome to my test server";
            data = Encoding.ASCII.GetBytes(welcome);
            client.Send(data, data.Length, SocketFlags.None);

            i = 0;


            while (true)
            {
                Console.WriteLine("polling for recieve #{0}...", i);
                i++;


                result = client.Poll(3000000, SelectMode.SelectRead);
                if (result)
                {
                    data = new byte[1024];
                    i = 0;
                    recv = client.Receive(data);


                    if (recv == 0)
                    {
                        break;
                    }


                    Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
                    client.Send(data, recv, 0);
                }
            }
            Console.WriteLine("Disconnected from {0}", newclient.Address);


            client.Close();
            newsock.Close();
        }
    }
}

 

 

테스트 클라이언트 : SimpleTcpClient.cs

 

여기에서는 while() 루프를 돌면서 SelectRead 속성에 대해서 소켓을 점검한다.

SelectRead 속성이 설정되어 있으면 Poll() 메소드는 true 값을 반환한다.

이 때 들어오는 연결 요청이 있기 때문에 Accept() 메소드를 블로킹없이 안전하게 호출할 수 있다.

 

Poll() 메소드는 1초에 한번씩 확인하도록 설정되어 있다.

Poll() 메소드 호출 중간 중간에 프로그램은 다른 메소드를 호출하는 등 여러 기능들을 수행할 수 있다.

 

이 프로그램은 단순히 카운터를 증가시키면서 콘솔에 표시하여 프로그램이 폴링 중에도 실행된다는 것을 보여준다.

 

들어오는 연결 요청을 수락하여 연결이 확립되면,

또 하나의 폴링 루프가 생성되어 Receive() 메소드에 대해서 들어오는 데이터를 대기한다.

이 때에도 역시 Poll() 메소드 호출 중간에 프로그램은 다른 필요한 오퍼레이션을 실행할 수 있다.

 

 

 


출처 http://blog.naver.com/PostView.nhn?blogId=kym2732&logNo=122986352&beginTime=0&jumpingVid=&from=search&redirect=Log&widgetTypeCall=true&topReferer=http%3A%2F%2Fsearch.naver.com%2Fsearch.naver%3Fwhere%3Dnexearch%26query%3Dselectmode.selectwrite%26sm%3Dtop_hty%26fbm%3D2%26ie%3Dutf8%26url%3Dhttp%253A%252F%252Fkym2732.blog.me%252F122986352%26ucs%3DfeYsFROq1CpF#


[출처] c# Poll 메소드|작성자 이얏호야

 

 

Posted by Mister_Q