CSharp
2013.04.26 11:36

비동기 소켓 클라이언트

조회 수 52963 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
Extra Form

비동기 소켓 클라이언트 클래스 만들어 봄.

.NET Compact Framework 2.0 용

사용법)

private void SockDataReceived(Socket sock, byte[] data, int readBytes)
{
  // 수신된 메시지 처리
}

...
AsyncSocketClient asc = new AsyncSocketClient();
asc.StartSend("192.168.1.100", 7788, "hello world\r\n", this.SockDataReceived, true);
...

현재 ASCII 엔코딩만 지원함.ㅋㅋㅋ

public class AsyncSocketClient
    {
        private byte[] txMessage;
        private Socket client;
        private Boolean doEndConnection;
        private DataReceivedCallback dataReceivedCallback;

        public delegate void DataReceivedCallback(Socket sock, byte[] data, int bytesRead);
        private class StateObject
        {
            // Client socket.
            public Socket workSocket = null;
            // Size of receive buffer.
            public const int BufferSize = 256;
            // Receive buffer.
            public byte[] buffer = new byte[BufferSize];
            // Received data string.
            public StringBuilder sb = new StringBuilder();
        }

        public AsyncSocketClient()
        {
            this.txMessage = null;
            this.client = null;
            this.doEndConnection = false;
            this.dataReceivedCallback = null;
        }

        public void SetDataReceivedCallback(DataReceivedCallback callback)
        {
            this.dataReceivedCallback = new DataReceivedCallback(callback);
        }

        private void ConnectCallback(IAsyncResult ar)
        {
            Socket s = (Socket)ar.AsyncState;
            try
            {
                s.EndConnect(ar);

                // 연결되었으면
                if (s.Connected)
                {
                    // 전송할 메시지가 있으면
                    if (this.txMessage != null)
                    {
                        // 전송한다.
                        s.Send(this.txMessage);
                    }
                    if (this.dataReceivedCallback != null)
                    {
                        // 수신시작
                        StateObject state = new StateObject();
                        state.workSocket = s;
                        s.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(this.ReceiveCallback), state);
                    }
                }
                else
                {
                    // 소켓 리소스 해제
                    s.Shutdown(SocketShutdown.Both);
                    s.Close();
                }
            }
            catch (Exception) { }
        }

        private void ReceiveCallback(IAsyncResult ar)
        {
            try
            {
                StateObject state = (StateObject)ar.AsyncState;
                Socket client = state.workSocket;

                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));

                    // 응용의 콜백 호출
                    if (this.dataReceivedCallback != null)
                    {
                        byte[] recvData = Encoding.ASCII.GetBytes(state.sb.ToString());
                        this.dataReceivedCallback(client, recvData, recvData.Length);
                    }

                    if (this.doEndConnection)
                    {
                        client.Shutdown(SocketShutdown.Both);
                        client.Close();
                    }
                    else
                    {
                        // Get the rest of the data.
                        client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(this.ReceiveCallback), state);
                    }
                }
                else
                {

                    if (client.Connected)
                    {
                        client.Shutdown(SocketShutdown.Both);
                        client.Close();
                    }
                }
            }
            catch (Exception e)
            {
                e.ToString();
            }
        }

        /// <summary>
        /// 현재 연결되어 있는 상태에서 전송하고 싶은 때 사용하라
        /// </summary>
        /// <param name="msg">전송하고싶은 문자열</param>
        /// <returns></returns>
        public Boolean Send(String msg)
        {
            if (this.client == null) return false;
            if (this.client.Connected == false) return false;
            return this.client.Send(Encoding.ASCII.GetBytes(msg)) > 0;
        }

        /// <summary>
        /// 최초 전송시작시 사용하라
        /// </summary>
        /// <param name="serverIP">대상 IP</param>
        /// <param name="port">대상 포트</param>
        /// <param name="msg">전송할 메시지</param>
        /// <param name="rxCallback">데이터 수신 콜백</param>
        /// <param name="doEndConnection">데이터 수신후 접속종료 여부</param>
        /// <returns></returns>
        public Boolean StartSend(String serverIP, int port, String msg, DataReceivedCallback rxCallback, Boolean doEndConnection)
        {
            // 이미 연결되어 있으면 소켓을 종료시킨다.
            if (this.client != null && this.client.Connected)
            {
                this.client.Shutdown(SocketShutdown.Both);
                this.client.Close();
            }

            this.client = null;
            this.doEndConnection = doEndConnection;
            this.SetDataReceivedCallback(rxCallback);

            try
            {
                // 소켓 생성
                IPAddress ipAddress = IPAddress.Parse(serverIP);
                IPEndPoint ipEP = new IPEndPoint(ipAddress, port);
                this.client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                // 전송할 데이터 지정
                this.txMessage = System.Text.Encoding.ASCII.GetBytes(msg);
                // 연결 시작
                IAsyncResult asyncResult = client.BeginConnect(ipEP, new AsyncCallback(this.ConnectCallback), this.client);
            }
            catch (Exception)
            {
                if (this.client != null)
                {
                    if (this.client.Connected)
                    {
                        this.client.Shutdown(SocketShutdown.Both);
                        this.client.Close();
                    }
                }
                return false;
            }
            return true;
        }
    }

List of Articles
번호 카테고리 제목 글쓴이 날짜 조회 수
182 Cpp Makefile - wildcard 비트겐스 2013.11.01 26733
181 Version Sub Version / svn update 시 특정 폴더 제외 비트겐스 2013.08.05 18875
180 Linux Fedora 18 - Login 화면에 사용자 목록 숨기기 비트겐스 2013.08.01 29958
179 Linux /usr/bin/rsync 비트겐스 2013.07.11 36942
» CSharp 비동기 소켓 클라이언트 비트겐스 2013.04.26 52963
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 39 Next
/ 39