Sử dụng các thông điệp với kích thước cố định

Một phần của tài liệu GT LAP TRINH MANG (Trang 39 - 44)

CHƯƠNG II: LẬP TRÌNH SOCKET HƯỚNG KẾT NỐI

II.4. L ậP TRÌNH S OCKET HƯớNG KếT NốI

II.4.6. Giải quyết các vấn đề với thông điệp TCP

II.4.6.1. Sử dụng các thông điệp với kích thước cố định

Cách dễ nhất nhƣng cũng là cách tốn chi phí nhất để giải quyết vấn đề với các thông điệp TCP là tạo ra các giao thức luôn luôn truyền các thông điệp với kích thước cố định. Bằng cách thiết lập tất cả các thông điệp có cùng kích thước, chương trình TCP nhận có thể biết toàn bộ thông điệp đƣợc gởi từ Client.

Khi gởi dữ liệu với kích thước cố định, chúng ta phải đảm bảo toàn bộ thông điệp được gởi từ phương thức Send(). Phụ thuộc vào kích thước của bộ đệm TCP và bao nhiêu dữ liệu được truyền, phương thức Send() sẽ trả về số byte mà nó thực sự đã gởi đến bộ đệm TCP. Nếu phương thức Send() chưa gởi hết dữ liệu thì chúng ta phải gởi lại phần dữ liệu còn lại. Việc này thường được thực hiện bằng cách sử dụng vòng lặp while() và trong vòng lặp ta kiểm tra số byte thực sự đã gởi với kích thước cố định.

private static int SendData(Socket s, byte[] data) {

int total = 0;

int size = data.Length;

int dataleft = size;

int sent;

while (total < size) {

sent = s.Send(data, total, dataleft, SocketFlags.None);

total += sent;

dataleft -= sent;

}

return total;

}

Trang 40

Cũng giống nhƣ việc gởi dữ liệu, chúng ta phải luôn luôn đảm bảo nhận tất cả dữ liệu trong phương thức Receive(). Bằng cách dùng vòng lặp gọi phương thức Receive() chúng ta có thể nhận đƣợc toàn bộ dữ liệu mong muốn.

private static byte[] ReceiveData(Socket s, int size) {

int total = 0;

int dataleft = size;

byte[] data = new byte[size];

int recv;

while (total < size) {

recv = s.Receive(data, total, dataleft, 0);

if (recv == 0) {

data = Encoding.ASCII.GetBytes("exit");

break;

}

total += recv;

dataleft -= recv;

}

return data;

Phương thức ReceiveData() sẽ đọc dữ liệu với kích thước được đọc là đối số được truyền vào, nếu phương thức Receive() sẽ trả về số byte thực sụ đọc được, nếu số byte thực sự đọc được mà còn nhỏ hơn số byte truyền vào phương thức ReceiveData() thì vòng lặp sẽ tiếp tục cho đến khi số byte đọc được đúng bằng kích thước yêu cầu.

Chương trình Server gởi và nhận dữ liệu với kích thước cố định

using System;

using System.Net;

using System.Net.Sockets;

using System.Text;

class FixedTcpSrvr {

private static int SendData(Socket s, byte[] data) {

int total = 0;

int size = data.Length;

Trang 41

int dataleft = size;

int sent;

while (total < size) {

sent = s.Send(data, total, dataleft, SocketFlags.None);

total += sent;

dataleft -= sent;

}

return total;

}

private static byte[] ReceiveData(Socket s, int size) {

int total = 0;

int dataleft = size;

byte[] data = new byte[size];

int recv;

while (total < size) {

recv = s.Receive(data, total, dataleft, 0);

if (recv == 0) {

data = Encoding.ASCII.GetBytes("exit");

break;

}

total += recv;

dataleft -= recv;

}

return data;

}

public static void Main() {

byte[] data = new byte[1024];

IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 5000);

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

newsock.Bind(ipep);

newsock.Listen(10);

Console.WriteLine("Dang cho Client ket noi den...");

Socket client = newsock.Accept();

IPEndPoint newclient = (IPEndPoint)client.RemoteEndPoint;

Console.WriteLine("Da ket noi voi Client {0} tai port {1}", newclient.Address, newclient.Port);

string welcome = "Hello Client";

Trang 42

data = Encoding.ASCII.GetBytes(welcome);

int sent = SendData(client, data);

for (int i = 0; i < 5; i++) {

data = ReceiveData(client, 12);

Console.WriteLine(Encoding.ASCII.GetString(data));

}

Console.WriteLine("Da ngat ket noi voi Client {0}", newclient.Address);

client.Close();

newsock.Close();

} }

Chương trình Client gởi và nhận dữ liệu với kích thước cố định

using System;

using System.Net;

using System.Net.Sockets;

using System.Text;

class FixedTcpClient {

private static int SendData(Socket s, byte[] data) {

int total = 0;

int size = data.Length;

int dataleft = size;

int sent;

while (total < size) {

sent = s.Send(data, total, dataleft, SocketFlags.None);

total += sent;

dataleft -= sent;

}

return total;

}

private static byte[] ReceiveData(Socket s, int size) {

int total = 0;

int dataleft = size;

byte[] data = new byte[size];

int recv;

while (total < size) {

Trang 43

recv = s.Receive(data, total, dataleft, 0);

if (recv == 0) {

data = Encoding.ASCII.GetBytes("exit ");

break;

}

total += recv;

dataleft -= recv;

}

return data;

}

public static void Main() {

byte[] data = new byte[1024];

int sent;

IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5000);

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

try {

server.Connect(ipep);

}

catch (SocketException e) {

Console.WriteLine("Khong the ket noi den server");

Console.WriteLine(e.ToString());

return;

}

int recv = server.Receive(data);

string stringData = Encoding.ASCII.GetString(data, 0, recv);

Console.WriteLine(stringData);

sent = SendData(server, Encoding.ASCII.GetBytes("Thong diep 1"));

sent = SendData(server, Encoding.ASCII.GetBytes("Thong diep 2"));

sent = SendData(server, Encoding.ASCII.GetBytes("Thong diep 3"));

sent = SendData(server, Encoding.ASCII.GetBytes("Thong diep 4"));

sent = SendData(server, Encoding.ASCII.GetBytes("Thong diep 5"));

Console.WriteLine("Dong ket noi voi server...");

server.Shutdown(SocketShutdown.Both);

server.Close();

} }

Kết quả trên Server

Trang 44

Một phần của tài liệu GT LAP TRINH MANG (Trang 39 - 44)

Tải bản đầy đủ (PDF)

(177 trang)