Những điều tuyệt vời về các tập tin và ổ cắm trong C# là họ đang cả hai tiếp xúc như suối. Sao chép tệp lớn từ luồng này sang luồng khác khá đơn giản:
byte[] data = new byte[1024];
while(true) {
int bytesRead = filestream.read(data,0,data.Length);
if (bytesRead==0) break;
netstream.write(data,0,bytesRead);
}
Sau đó, chỉ cần đóng ổ cắm khi bạn hoàn tất.
Nếu bạn muốn gửi siêu dữ liệu (tên tệp, kích thước) hoặc không muốn đóng kết nối, bạn cần một số loại giao thức để xử lý việc này. FTP sử dụng hai ổ cắm riêng biệt (một cho siêu dữ liệu, một cho dữ liệu; điều này được gọi là truyền thông ngoài băng thông). Nếu bạn đang ở trên mạng LAN không có tường lửa, điều đó có thể được chấp nhận hoàn toàn. Mặt khác, nếu bạn muốn thực hiện chuyển giao internet, việc mở một cổng duy nhất là một nhiệm vụ khó khăn và cả hai đều không thể chịu nổi. Nếu bạn không quan tâm quá nhiều về hiệu suất, bạn có thể mã hóa các byte trong mã hóa base64, điều này đảm bảo rằng chúng nằm trong một phạm vi byte nhất định. Với base64, bạn có thể tách riêng các thư với dòng mới hoặc các ký tự không phải chữ và số khác. Sau đó, trong tin nhắn đầu tiên bao gồm tên tệp, kích thước hoặc bất kỳ thứ gì, sau đó gửi dữ liệu dưới dạng tin nhắn thứ hai, sau đó gửi thông báo "đó là toàn bộ tệp" để khách hàng biết nó đã hoàn tất.
Một chiến thuật khác cho các thư đang sử dụng chuỗi thoát. Ví dụ, lấy bytestream của bạn và thay thế mỗi instance của '\ 0' bằng '\ 0 \ 0'. Bây giờ sử dụng '\ 0 \ 1' để báo hiệu phần cuối của tin nhắn, được đảm bảo không được chứa trong thông điệp dữ liệu của bạn. Giải mã '\ 0 \ 0' quay lại '\ 0' trên đầu nhận.Điều này hoạt động tốt trong C, nhưng tôi thấy rằng, trong thực tế, lặp qua từng byte có thể chậm hơn so với việc đọc toàn bộ bộ đệm trong C#.
Cách tốt nhất là áp dụng một số loại giao thức có chiều dài thích ứng. Ví dụ, gửi dữ liệu trong các khối của một kích thước nhất định (nói 512 byte). Trước mỗi đoạn, gửi một 32 bit int đại diện cho kích thước của đoạn thông qua System.BitConverter. Vì vậy, thông điệp giống như thế này (tiếng Anh):
Here's 512 bytes:
[data]
Here's 512 bytes:
[data]
Here's 32 bytes:
[data]
Here's 4 bytes:
That was the whole file
Ưu điểm ở đây là bạn có thể làm cho sao chép/đọc bộ đệm làm việc cho bạn (đọc 512 byte tại một thời điểm), có nghĩa là thông lượng của bạn bị hạn chế bởi ngăn xếp mạng của bạn thay vì mã C# của bạn. Máy khách đọc int 32-bit có độ dài cố định cho phép nó biết kích thước của bộ đệm mà nó sẽ sử dụng cho phân đoạn [dữ liệu] tiếp theo.
Dưới đây là một số mã để viết tin nhắn như thế:
logger.logger.debug("Sending message of length " + length);
byte[] clength = System.BitConverter.GetBytes(buffer.Length);
plaintextStream.Write(clength,0,clength.Length);
plaintextStream.Write(buffer,0,buffer.Length);
plaintextStream.Flush();
Và đây là một số mã để đọc chúng:
byte[] intbuf = new byte[int_32_size];
int offset = 0;
while (offset < int_32_size)
{
int read = 0;
read = d.plaintextStream.Read(intbuf,offset,int_32_size - offset);
offset += read;
}
int msg_size = System.BitConverter.ToInt32(intbuf,0);
//allocate a new buffer to fill the message
byte[] msg_buffer = new byte[msg_size];
offset = 0;
while (offset < msg_size)
{
int read = 0;
read = d.plaintextStream.Read(msg_buffer,offset,msg_size - offset);
offset += read;
}
return msg_buffer;
Các lớp ASP.Net? Tôi đang tìm kiếm sự tương tác giữa các ứng dụng Windows. –
Ý bạn là gì? Không có lớp nào tôi đề cập đến là các lớp ASP .NET. – driis