프로그램 설명
이번 예제는 연결된 클라이언트, 모두에게 메시지를 전송하는 코드입니다.
서버는 접속 커넥션을 기달렸다가 클라이언트가 접속을 하게 되면 각 접속은 새로운 쓰레드가 담당을 관리합니다.
서버는 모든 연결된 클라이언트를 array list 로 관리를 합니다.
클라이언트가 메시지를 서버에게 전달을 하게 되면, 쓰레드가 본인 클라이언트만 제외하고 모든 접속 된 클라이언트에게 메시지를 전달합니다.
실행 후
메시진 전송 후
프로그램 작성 순서
1. 공통 라이브러리
using System.Net; using System.Net.Sockets; using System.Threading; using System.IO;
2. 서버 프로그램
class Program { private static TcpListener server; private static List<tcpclient> clientList = new List<tcpclient>(); static void Main(string[] args) { server = new TcpListener(IPAddress.Any, 12340); server.Start(); Console.WriteLine("server started\n"); Console.WriteLine("waiting for a client"); while(true) { TcpClient client = server.AcceptTcpClient(); clientList.Add(client); Thread t_handler = new Thread(new ParameterizedThreadStart(ClientListener)); t_handler.Start(client); // 디버깅 용 Debug.WriteLine("Thread count = {0}", Process.GetCurrentProcess().Threads.Count); } } static void ClientListener(object sender) { TcpClient client = null; StreamReader sr = null; try { client = sender as TcpClient; sr = new StreamReader(client.GetStream()); Console.WriteLine("New Client connected\n"); while (true) { string message = sr.ReadLine(); if (!string.IsNullOrEmpty(message)) { BroadCast(message, client); Console.WriteLine("received data : {0}\n", message); } } } catch (SocketException se) { Console.WriteLine("SocketException : {0}\n", se.Message); } catch (Exception ex) { Console.WriteLine("Exception : {0}\n", ex.Message); } finally { Console.WriteLine("client disconnected\n"); clientList.Remove(client); sr.Close(); client.Close(); Thread.CurrentThread.Abort(); } } static void BroadCast(string message, TcpClient excludeClient) { foreach(TcpClient client in clientList) { if (client != excludeClient) { StreamWriter sw = new StreamWriter(client.GetStream()); sw.WriteLine(message); sw.Flush(); } } } }
3. 클라이언트 프로그램
static void Main(string[] args) { TcpClient client = null; StreamWriter sw = null; try { client = new TcpClient("192.168.0.12", 12340); Console.WriteLine("Connected to server.\n"); Thread c_thread = new Thread(new ParameterizedThreadStart(Client_Read)); c_thread.Start(client); sw = new StreamWriter(client.GetStream()); while(true) { if (client.Connected) { Console.Write("send data : "); string input = Console.ReadLine(); sw.WriteLine(input); sw.Flush(); } else break; } } catch (SocketException se) { Console.WriteLine("SocketException : {0}", se.Message); } catch (Exception ex) { Console.WriteLine("Exception : {0}", ex.Message); } finally { sw.Close(); client.Close(); } Console.WriteLine("Press the ENTER key to continue..."); Console.ReadLine(); } static void Client_Read(object sender) { TcpClient client = sender as TcpClient; StreamReader sr = new StreamReader(client.GetStream()); try { while(true) { string message = sr.ReadLine(); if (!string.IsNullOrEmpty(message)) Console.WriteLine("\nreceived data : {0}\n", message); } } catch(SocketException se) { Console.WriteLine("SocketException : {0}\n", se.Message); } catch(Exception ex) { Console.WriteLine("Exception : {0}\n", ex.Message); } finally { sr.Close(); client.Close(); } }
'C# with TCP/IP' 카테고리의 다른 글
[Program C#] 비동기 접속 - 윈도우폼 (0) | 2015.03.06 |
---|---|
[Program C#] 라이브러리를 이용한 클라이언트-서버 소켓 (0) | 2015.02.25 |
[Program C#]Binary Serialization 을 이용한 소켓통신 - 윈도우버전 (0) | 2015.01.31 |
[Program C#]Binary Serialization 을 이용한 소켓통신 - 콘솔버전 (0) | 2015.01.28 |
[Program C#]구조체를 이용한 소켓통신3 - 바이너리 포매터 방법 - 윈도우 버전 (0) | 2015.01.27 |