Параллельная работа сокетов в C#
Потоки в C# using System; using System.Threading; public class ThreadExample { public static void ThreadProc() { for (int i = 0; i < 10; i++) { Console.WriteLine("ThreadProc: {0}", i); Thread.Sleep(0); }
Потоки в C# public static void Main() { Console.WriteLine("Main thread: Start a second thread."); Thread t = new Thread(new ThreadStart(ThreadProc)); t.Start(); for (int i = 0; i < 4; i++) { Console.WriteLine("Main thread: Do some work."); Thread.Sleep(0); } Console.WriteLine("Main thread: Call Join()"); t.Join(); Console.WriteLine("Main thread: ThreadProc.Join has returned"); Console.ReadLine(); }
Потоки в C# Объявление и создание потока, указывается метод-цель Thread t = new Thread(new ThreadStart(ThreadProc)); Запуск потока t.Start(); Приостановка потоков t.Suspend(); Возобновление приостановленного потока t.Resume();
Потоки в C# Ожидание завершения потока t.Join(); Состояние ожидания и передача управления Thread.Sleep(0);
1 шаг изменения программы-сервера Создадим метод run(), в задачи которого входит создание потока, чтение данных, их преобразование и запись в поток. Фактически, здесь сосредоточена вся работа с клиентом. Подключим: using System.IO; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading;
Глобально объявим: public static TcpClient client; public static TcpListener server; private static System.Threading.Thread t;
Метод run() public static void run(TcpClient client) { Byte[] bytes = new Byte[256]; NetworkStream stream = client.GetStream(); int i; i = stream.Read(bytes, 0, bytes.Length); String data = System.Text.Encoding.UTF8.GetString(bytes, 0, i); Console.WriteLine(String.Format("Received: {0}", data)); data = data.ToUpper(); byte[] msg = System.Text.Encoding.UTF8.GetBytes(data); stream.Write(msg, 0, msg.Length); Console.WriteLine(String.Format("Sent: {0}", data)); client.Close(); Console.WriteLine("Close"); }
2 шаг используем метод run в цикле ожидания подключения клиента while(true) { Console.Write("Waiting for a connection... "); client = server.AcceptTcpClient(); Console.WriteLine("Connected!"); run(client); } Пока клиенты работают с сервером последовательно.
3 шаг -используем потоки для обеспечения параллельной работы сокетов Добавим: using System.Threading; Глобально объявим: private System.Threading.Thread t; Создадим метод public static void ThreadProc() { run(client); }
4 шаг - создадим поток в цикле ожидания подключения клиента while(true) { Console.Write("Waiting for a connection... "); client = server.AcceptTcpClient(); Console.WriteLine("Connected!"); t=new Thread(new ThreadStart(ThreadProc)); t.Start(); }
5 шаг запуск сервера оформим в виде метода serverwork() public static void serverwork() { try { Int32 port=13000; IPAddress localAddr=IPAddress.Parse(" "); server=new TcpListener(localAddr,port); server.Start(); Byte[] bytes = new Byte[256]; while(true) {
Console.Write("Waiting for a connection... "); client = server.AcceptTcpClient(); Console.WriteLine("Connected!"); //run(client); t=new Thread(new ThreadStart(ThreadProc)); t.Start(); } catch(SocketException ex) { Console.WriteLine("SocketException: {0}", ex); }
6 шаг создадим метод, который запускает сервер public static void ThreadProc1() { serverwork(); }
7 шаг – кнопка «Запуск сервера» private void button3_Click(object sender, System.EventArgs e) { t=new Thread(new ThreadStart(ThreadProc1)); t.Start(); }
8 шаг – кнопка «Останов сервера» private void button2_Click(object sender, System.EventArgs e) { if (server!=null) { server.Stop(); t.Abort(); }
9 шаг – событие «Закрытие формы» private void Form1_Closed(object sender, System.EventArgs e) { if (server!=null) { server.Stop(); t.Abort(); }