chantroitinhoc

Joined : 10 Jan 2008 Posts : 24
 | Subject: CHUONG TRINH CHAT VIET BANG C# 23/5/2008, 15:20 | |
| I. Giới thiệu Chương tŕnh cho phép thực hiện việc giao tiếp giữa các clients thông qua server,
II. Nội dung Sử dụng luồng tại server, mỗi khi client kết nối đến server chương tŕnh sẽ tạo những luồng riêng biệt để xử lư các kết nối, chương tŕnh cũng tạo ra những luồng để xử lư các client mới. Chương tŕnh được mô tả cụ thể như sau:
Chương tŕnh ThreadedTcpSrvr.cs
| Code: | using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; class ThreadedTcpSrvr { private TcpListener client; public ThreadedTcpSrvr() { client = new TcpListener(9050); client.Start(); Console.WriteLine("Waiting for clients..."); while(true) { while (!client.Pending()) { Thread.Sleep(1000); } ConnectionThread newconnection = new ConnectionThread(); newconnection.threadListener = this.client; Thread newthread = new Thread(new ThreadStart(newconnection.HandleConnection)); newthread.Start(); } } public static void Main() { ThreadedTcpSrvr server = new ThreadedTcpSrvr(); } } class ConnectionThread { public TcpListener threadListener; private static int connections = 0; public void HandleConnection() { int recv; byte[] data = new byte[1024]; TcpClient client = threadListener.AcceptTcpClient(); NetworkStream ns = client.GetStream(); connections++; Console.WriteLine("New client accepted: {0} active connections", connections); string welcome = "Welcome to my test server"; data = Encoding.ASCII.GetBytes(welcome); ns.Write(data, 0, data.Length); while(true) { data = new byte[1024]; recv = ns.Read(data, 0, data.Length); if (recv == 0) break; ns.Write(data, 0, recv); } ns.Close(); client.Close(); connections --; Console.WriteLine("Client disconnected: {0} active connections", connections); } }
|
Chương tŕnh sử dụng lớp Tcp Listener để lắng nghe các kết nối TCP theo cổng cố định (9050) đồng thời phương thức start() được sử dụng để chờ các clients mới.
| Code: | while(true) { while (!client.Pending()) { Thread.Sleep(1000); } ConnectionThread newconnection = new ConnectionThread(); newconnection.threadListener = this.client; Thread newthread = new Thread(new ThreadStart(newconnection.HandleConnection)); newthread.Start(); }
|
Ṿng lặp while được sử dụng để kiểm tra các client kết nối, nếu có chương tŕnh sẽ tạo luồng để chấp nhận các kết nối. Khi server chấp nhận các kết nối từ phía client, nó sẽ tạo ra socket riêng biệt và đưa vào một luồng mới. Một client có thể gửi tin nhắn đến một client và nhận được phản hồi từ chính client đó mà không ảnh hưởng đến các client khác. Khi mỗi client ngắt kết nối, luồng sẽ tự động ngắt. Chương tŕnh dưới đây thực hiện việc gửi và nhận dữ liệu giữa các client thông qua giao thức TCP
Chương tŕnh TCPChat.cs
| Code: | using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms;
using System.Net.Sockets; using System.Net;
using System.Threading;
namespace TcpChat { public partial class TcpChat : Form { public TcpChat() { InitializeComponent(); } private static Socket client; private static byte[] data = new byte[1024];
void AcceptConn(IAsyncResult iar) { Socket oldserver = (Socket)iar.AsyncState; client = oldserver.EndAccept(iar); results.Items.Add("Connection from: " + client.RemoteEndPoint.ToString()); Thread receiver = new Thread(new ThreadStart(ReceiveData)); receiver.Start(); } void Connected(IAsyncResult iar) { try { client.EndConnect(iar); results.Items.Add("Connected to: " + client.RemoteEndPoint.ToString()); Thread receiver = new Thread(new ThreadStart(ReceiveData)); receiver.Start(); } catch (SocketException) { results.Items.Add("Error connecting"); } } void SendData(IAsyncResult iar) { Socket remote = (Socket)iar.AsyncState; int sent = remote.EndSend(iar); } void ReceiveData() { int recv; string stringData; while (true) { recv = client.Receive(data); stringData = Encoding.ASCII.GetString(data, 0, recv); if (stringData == "bye") break; results.Items.Add(stringData); } stringData = "bye"; byte[] message = Encoding.ASCII.GetBytes(stringData); client.Send(message); client.Close(); results.Items.Add("Connection stopped"); return; }
private void btnlisten_Click(object sender, EventArgs e) { results.Items.Add("Listening for a client..."); Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint iep = new IPEndPoint(IPAddress.Any, 9050); newsock.Bind(iep); newsock.Listen(5); newsock.BeginAccept(new AsyncCallback(AcceptConn), newsock); }
private void btnconnect_Click(object sender, EventArgs e) { results.Items.Add("Connecting..."); client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iep = new IPEndPoint(IPAddress.Parse(txtip.Text), 9050); client.BeginConnect(iep, new AsyncCallback(Connected), client); }
private void btnsend_Click(object sender, EventArgs e) { byte[] message = Encoding.ASCII.GetBytes(txttext.Text); txttext.Clear(); client.BeginSend(message, 0, message.Length, 0, new AsyncCallback(SendData), client); }
} }
|
Chương tŕnh được tạo dưới dạng form đơn giản với các đối tượng cụ thể sau: o Một textbox (txtip) cho phép nhập địa chỉ ip kết nối o Textbox (txttext): nhập nội dung gửi đi o Nút listen chờ nhận kết nối từ máy client khác o Nút connect thực hiện các kết nối đến các máy khác từ xa o Nút send thực hiện gửi tin nhắn đến các máy client được nhập vào từ textbox (txttext). o Listbox (result) hiển thị nội dung chat giữa các client với nhau. o Khi người dùng nhấn nút listen một socket sẽ được tạo ra và lắng nghe các kết nối đang đến sử dụng phương thức beginAccept():
| Code: | private void btnlisten_Click(object sender, EventArgs e) { results.Items.Add("Listening for a client..."); Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint iep = new IPEndPoint(IPAddress.Any, 9050); newsock.Bind(iep); newsock.Listen(5); newsock.BeginAccept(new AsyncCallback(AcceptConn), newsock); }
|
Khi một chương tŕnh chat khác kết nối., phương thức AcceptConn() tạo ra những socket riêng biệt cho mỗi client. Khi khách hàng nhấn nút connect, một socket được tao ra và cố gắng để kết nối đến host từ xa, sử dụng phương thức beginconnect(). Sau khi host từ xa chấp nhận kết nối. Một socket được đưa đến luồng tạm thời, mục đích của luồng tạm thời này là chờ dữ liệu đến và đưa dữ liệu vào trong listbox
| Code: | void ReceiveData() { int recv; string stringData; while (true) { recv = client.Receive(data); stringData = Encoding.ASCII.GetString(data, 0, recv); if (stringData == "bye") break; results.Items.Add(stringData); } stringData = "bye"; byte[] message = Encoding.ASCII.GetBytes(stringData); client.Send(message); client.Close(); results.Items.Add("Connection stopped"); return; }
|
Khi dữ liệu gửi đi có chuỗi “bye”, chương tŕnh sẽ tự động đóng socket, cả hai chương tŕnh chat bị ngắt và đóng kết nối Tcp. Minh họa chương tŕnh chat giữa 2 client thông qua server: Chương tŕnh được minh họa trên 2 máy khác nhau, máy 1 với địa chỉ ip: 172.16.71.13 đóng vai tṛ là máy server và client, máy 2 với địa chỉ ip: 172.17.71.160 là máy client
Đầu tiên chạy chương tŕnh ThreadedTcpSrvr trên máy 1
Mở chương tŕnh TcpChat tại máy 1 và máy 2. Giả sử hai chương tŕnh này được chạy cùng thời điểm đang xét. Hai máy đồng thời thực hiện việc kết nối đến server IP: 172.16.71.13
Bây giờ bắt đầu kết nối 2 client để chat trực tiếp với nhau. Giả sử máy 2 giữ vai tṛ chờ kết nối nhấn nút Listen. Máy 1 sẽ giữ vai tṛ kết nối, nhập địa chỉ ip máy 2: 172.168.71.160 và nhấn nút Connect khi đó 2 client có thể chat với nhau trực tiếp.
Sau khi kết nối được thiết lập, 2 máy có thể gửi nhận tin nhắn qua lại với nhau:
Chương tŕnh sẽ tự động ngắt kết nối khi một trong hai máy gửi tin nhắn với chuỗi kư tự “bye” _________________ A person who never made a mistake never tried anything new! http://www.echip.com.vn http://www.pcworld.com.vn http://www.khoahocphothong.com.vn |
|