programing/C#

[C#]Socket - 버퍼 사이즈보다 많은 양의 데이터 전송.

쪽제비 2016. 8. 29. 12:28

DataSet을 Byte로 변환하여 보낼일이 생겼다.

그런데.. DataSet의 크기가 크다. 

문제가 또 생긴 것이 Byte로 받은 측에서 DataSet으로 변경할 때 생긴다.

버퍼 크기대로 받으면. DataSet으로 변경이 안되기 때문이다.

그래서 DataSet의 크기를 먼저 보낸 후 그 사이즈와 버퍼 사이즈를 비교하여 반복적으로 받는 방법이다.


출처 : http://it-jerryfamily.tistory.com/entry/ProgramSocket-%ED%86%B5%EC%8B%A0-%EB%B2%84%ED%8D%BC-%EC%82%AC%EC%9D%B4%EC%A6%88%EB%B3%B4%EB%8B%A4-%EB%A7%8E%EC%9D%80-%EC%96%91%EC%9D%98-%EB%8D%B0%EC%9D%B4%ED%83%80%EB%A5%BC-%EB%B0%9B%EC%9D%84-%EC%8B%9C



위의 출처로 가면 소스가 나와 있다.



주요 부분만 설명.


서버 (받는 측)


 private void btnListen_Click(object sender, EventArgs e)
    {
        sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 
        sck.Bind(new IPEndPoint(0, 8));
        sck.Listen(0);
 
        acc = sck.Accept();
 
        sck.Close();
 
        new Thread(() =>
        {
            while(true)
            {
                try
                {
///////// 받을 Data의 크기를 먼저 알아온다.
                    byte[] sizeBuf = new byte[4];
 
                    acc.Receive(sizeBuf, 0, sizeBuf.Length, 0);
 
                    int size = BitConverter.ToInt32(sizeBuf, 0);
//////// 데이터를 반복적으로 가져 올때 Stream에다가 저장 한다.
                    MemoryStream ms = new MemoryStream();
                     
/////// 받을 Data의 크기와 버퍼 사이즈를 비교하면서 데이터를 받아 온다.
                    while (size > 0)
                    {
                        byte[] buffer;
                        if (size < acc.ReceiveBufferSize)
                            buffer = new byte[size];
                        else
                            buffer = new byte[acc.ReceiveBufferSize];
 
                        int rec = acc.Receive(buffer, 0, buffer.Length, 0);
 
                        size -= rec;
 
                        ms.Write(buffer, 0, buffer.Length);
                    }
 
                    ms.Close();
 
                    byte[] data = ms.ToArray();
 
                    ms.Dispose();
 
                    Invoke((MethodInvoker)delegate
                    {
                        richTextBox1.Text = Encoding.UTF8.GetString(data);
                    });
                }
                catch
                {
                    MessageBox.Show("서버: DISCONNECTION!");
                    acc.Close();
                    acc.Dispose();
                    break;
                }
            }
            Application.Exit();
        }).Start();
    }


클라이언트 (보내는 측)


private void btnSendText_Click(object sender, EventArgs e)
{
    byte[] data = Encoding.UTF8.GetBytes(richTextBox1.Text);
     //보낼 데이터의 크기를 먼저 보낸다.
    sck.Send(BitConverter.GetBytes(data.Length), 0, 4, 0);
//데이터를 보낸다.
    sck.Send(data);
}