[C#] Socket C# 2012. 2. 23. 14:16

문득 생각나서 한번 작성해 본 코드이다.

.NET 에서 제공하는 리스너가 아닌 소켓만으로 작성한 예이다.

일반적으로 코드 내용은 같다.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;

namespace Server
{
    public partial class Form1 : Form
    {

        IPEndPoint _ip_end_point;
        Socket _server;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                this._ip_end_point = new IPEndPoint(IPAddress.Any, 10000);
                this._server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);               
                this._server.Bind(this._ip_end_point);
                this._server.Listen(100);

                while (true)
                {
                    Application.DoEvents();
                    Socket client = this._server.Accept();

                    int recv_total = 0;
                    int recv_size = 0;
                    int left_data = 0;
                    int recv_data = 0;

                    byte[] size = new byte[4];
                    recv_data = client.Receive(size, 0, 4, SocketFlags.None);
                    recv_size = BitConverter.ToInt32(size, 0);
                    left_data = recv_size;

                    byte[] data = new byte[recv_size];

                    while (recv_total < recv_size)
                    {
                        Application.DoEvents();
                        recv_data = client.Receive(data, recv_total, left_data, 0);
                        if (recv_data == 0)
                        {
                            this.Text = "Zero Data";
                            break;
                        }
                        else
                        {
                            this.Text = "No Zero Data";
                            recv_total += recv_data;
                            left_data -= recv_data;
                        }
                    }
                    client.Close();
                    MessageBox.Show(Encoding.Default.GetString(data, 0, recv_size));
                }
            }
            catch
            {
            }
            finally
            {
                this._server.Close();
            }
        }
    }
}
코드에서 보면 알겠지만 엔드 포인트를 잡아주고 그것을 바인드 한 형태이다.

하나 의문인게 Listen 처리를 하지 않으면 안될까.. 고민 하다가 한번 빼 보고 했는데 바로 오류가 났다.

한 소켓에 접근하는 수를 제어하는 것인데 여러 수천, 수만명이 접근 할 때는 어떻게 되는 것인가 의문이 든다.

한번 연구 해 볼 만한 가치는 있는 듯 하다.(경력에 비해 해 본 것이 없는 것 같아 슬프다.)

나머지는 대략 접속한 소켓을 생성하고 그 내용을 바이트 처리 하여 하는 것이다. 여기까지가 서버 코드이다.

다음은 클라이언트 코드이다.

try
            {
                IPEndPoint ip_end_point = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 10000);
                Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                server.Connect(ip_end_point);

                int send_total = 0;
                int data_size = 0;
                int left_data = 0;
                int send_data = 0;

                EventHandler();

                byte[] data = new byte[data_size];
                data = Encoding.Default.GetBytes("TCP/IP Connect Test");
                data_size = data.Length;
                left_data = data_size;

                byte[] size = new byte[4];
                size = BitConverter.GetBytes(data_size);

                server.Send(size);

                while (send_total < data_size)
                {
                    send_data = server.Send(data, send_total, left_data, SocketFlags.None);
                    send_total += send_data;
                    left_data -= send_data;
                }
            }
            catch
            {
            }
            finally
            {
                server.Close();
            }
최초의 작업은 서버 측과 동일하다. 엔드 포인트를 잡아주고 소켓을 생성해서 서버와 접속을 한다.

물론 데이터 처리는 서버와 동일하게 하기 위해서 바이트 처리를 하게 해봤다.

이것 말고도 네트워크 스트림을 이용하여 스트림을 이용해서 문자열들을 보내는 통신 또한 가능하다.

각기 해당하는 스트림을 생성하여 Flash() 처리를 해 주면 된다.

그렇게 작업 할 경우 반드시 스트림 처리엔 Flash() 처리를 해 줘야한다. 아닐 경우 버퍼에 쌓인 데이터 문제도 있을 뿐더러

통신 결과가 원할하지 않거나 문제가 발생하는 것을 확인 할 수가 있을 것이다.