C# – Tìm hiểu về gửi và nhận DataTable qua Socket

Trong bài này, tôi sẽ làm một ví dụ về gửi và nhận DataTable qua Socket trong C#. Bạn có thể thay DataTable bằng Dataset. Code tôi để ở chế độ mở (dùng object) nên bạn có thể làm được điều này.
Phương thức này dùng để Serialize một đối tượng bất kỳ thành mảng byte

1 	public byte[] SerializeData(Object o)
2 	      {
3 	          MemoryStream ms = new MemoryStream();
4 	          BinaryFormatter bf1 = new BinaryFormatter();
5 	          bf1.Serialize(ms, o);
6 	          return ms.ToArray();
7 	      }

Phương thức này dùng để DeSerialize một mảng byte thành đối tượng bất kỳ

1 	public object DeserializeData(byte[] theByteArray)
2 	        {
3 	            MemoryStream ms = new MemoryStream(theByteArray);
4 	            BinaryFormatter bf1 = new BinaryFormatter();
5 	            ms.Position = 0;
6 	            return bf1.Deserialize(ms);
7 	        }

Tạo Solution

Bạn tạo 1 solution có tên chẳng hạn là SocketInCSharp.
1. Đầu tiên là ở server: Add 1project, đặt tên là SocketServer, thêm 1 form và trên form thêm 1 nút có tên Start. Kết quả như sau:
server

Source code như sau:

01 	using System;
02 	using System.Collections.Generic;
03 	using System.ComponentModel;
04 	using System.Data;
05 	using System.Drawing;
06 	using System.Text;
07 	using System.Windows.Forms;
08 	using System.Net;
09 	using System.Net.Sockets;
10 	using System.Runtime.Serialization;
11 	using System.Runtime.Serialization.Formatters.Binary;
12 	using System.IO;
13 	namespace SocketServer
14 	{
15 	    public partial class Form1 : Form
16 	    {
17 	        private Socket sock = null;
18 	        public Form1()
19 	        {
20 	            InitializeComponent();
21 	        }
22 	 
23 	        private void startButton_Click(object sender, EventArgs e)
24 	        {
25 	            startButton.Text = "In process...";
26 	            Application.DoEvents();
27 	 
28 	            IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, 5656);
29 	            sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
30 	            sock.Bind(ipEnd);
31 	            sock.Listen(100);
32 	            Socket clientSock = sock.Accept();
33 	            DataTable table = getdata();
34 	            clientSock.Send(SerializeData(table));
35 	 
36 	            sock.Close();
37 	            clientSock.Close();
38 	            startButton.Text = "&Start Server";
39 	            Application.DoEvents();
40 	        }
41 	 
42 	        public byte[] SerializeData(Object o)
43 	        {
44 	            MemoryStream ms = new MemoryStream();
45 	            BinaryFormatter bf1 = new BinaryFormatter();
46 	            bf1.Serialize(ms, o);
47 	            return ms.ToArray();
48 	        }
49 	 
50 	       /*Ở đây tôi tạo 1 bảng dữ liệu thử.
51 	Bạn có thể kết nối csdl và load dữ liệu lên*/
52 	       private DataTable getdata()
53 	        {
54 	            DataTable dt = new DataTable();
55 	            DataRow dr;
56 	 
57 	            dt.Columns.Add(new DataColumn("IntegerValue", typeof(Int32)));
58 	            dt.Columns.Add(new DataColumn("StringValue", typeof(string)));
59 	            dt.Columns.Add(new DataColumn("DateTimeValue", typeof(DateTime)));
60 	            dt.Columns.Add(new DataColumn("BooleanValue", typeof(bool)));
61 	 
62 	            for (int i = 1; i <= 1000; i++)
63 	            {
64 	                dr = dt.NewRow();
65 	                dr[0] = i;
66 	                dr[1] = "Item " + i.ToString();
67 	                dr[2] = DateTime.Now;
68 	                dr[3] = (i % 2 != 0) ? true : false;
69 	 
70 	                dt.Rows.Add(dr);
71 	            }
72 	            return dt;
73 	        }
74 	    }
75 	}

Biên dịch chương trình sau đó mở thư mục bin/Debug để chạy tập tin SocketServer.exe. Nhấn nút Start Server để bắt đầu chạy server. Mỗi lần gửi xong phải nhấn nút start một lần. Bạn có thể dùng Threading để cho nó chạy liên tục, tuy nhiên bạn sẽ phải xem đến phương thức SendAsync của socket.

2. Ở phía Client: Bạn Thêm 1 project khác có tên SocketClient vào Solution. Thêm vào 1 textbox để nhập server address, một nút nhấn để nhận dữ liệu. Thiết kế như sau

clientdesign

Source code cho form này như sau:

01 	using System;
02 	using System.Collections.Generic;
03 	using System.ComponentModel;
04 	using System.Data;
05 	using System.Drawing;
06 	using System.Text;
07 	using System.Windows.Forms;
08 	using System.IO;
09 	using System.Net;
10 	using System.Net.Sockets;
11 	 
12 	using System.Runtime.Serialization;
13 	using System.Runtime.Serialization.Formatters.Binary;
14 	 
15 	namespace SocketClient
16 	{
17 	    public partial class Form1 : Form
18 	    {
19 	        public Form1()
20 	        {
21 	            InitializeComponent();
22 	        }
23 	 
24 	        public object DeserializeData(byte[] theByteArray)
25 	        {
26 	            MemoryStream ms = new MemoryStream(theByteArray);
27 	            BinaryFormatter bf1 = new BinaryFormatter();
28 	            ms.Position = 0;
29 	            return bf1.Deserialize(ms);
30 	        }
31 	 
32 	        private void receiveButton_Click(object sender, EventArgs e)
33 	        {
34 	            try
35 	            {
36 	                IPAddress[] ipAddress = Dns.GetHostAddresses(serverTextBox.Text);
37 	                IPEndPoint ipEnd = new IPEndPoint(IPAddress.Parse("127.0.0.1"),5656);
38 	                Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
39 	                clientSock.Connect(ipEnd);
40 	                byte[] data = new byte[1024 * 5000];
41 	                clientSock.Receive(data);
42 	                DataTable dt = (DataTable)DeserializeData(data);
43 	                dataGridView1.DataSource = dt;
44 	                clientSock.Close();
45 	            }
46 	            catch (Exception ex)
47 	            {
48 	                MessageBox.Show(ex.Message);
49 	            }
50 	        }
51 	    }
52 	}

Kết quả sau khi nhấn nút nhận dữ liệu
clientresult