1. select
: 리스트 안에 있는 소켓의 상태를 확인한다. ( 데이타가 들어왔는지 , 데이타를 쓰는지 등등)
데이타가 들어온 소켓만 따로 리스트를 만든다.
원본 리스트는 회손된다.
https://docs.microsoft.com/ko-kr/dotnet/api/system.net.sockets.socket.select?view=net-5.0
Socket.Select(IList, IList, IList, Int32) 메서드 (System.Net.Sockets)
하나 이상의 소켓 상태를 확인합니다.Determines the status of one or more sockets.
docs.microsoft.com
서버
using System;
using System.Collections;
using System.Data;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace NetSocket_Server_002
{
class SmartServer
{
private Thread aThread;
private Socket aSocket;
private ArrayList aSocketList;
private string IP;
private int Port;
public SmartServer() : this("192.168.0.110", 5000)
{
}
public SmartServer(string IP) : this(IP, 5000)
{
}
public SmartServer(int Port) : this("192.168.0.110", Port)
{
}
public SmartServer(string IP, int Port)
{
this.IP = IP;
this.Port = Port;
this.aSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
this.aSocket.Bind(new IPEndPoint(IPAddress.Parse(this.IP), this.Port));
this.aSocket.Listen(5);
this.aSocketList = new ArrayList();
this.aSocketList.Add(aSocket);
aThread = new Thread(Receiver);
}
private void SendTOClient(byte[] aData,int iSize)
{
foreach (Socket User in aSocketList)
{
if (User == aSocket)
{
continue;
}
User.Send(aData, 0, iSize, SocketFlags.None);
}
}
private void SendTOClient(Socket RSoket,byte[] aData, int iSize)
{
foreach (Socket User in aSocketList)
{
if (User == RSoket)
{
continue;
}
if (User == aSocket)
{
continue;
}
User.Send(aData, 0, iSize, SocketFlags.None);
}
}
private void Receiver()
{
ArrayList aSocketList_Temp;
byte[] aData = new byte[1024];
string aString;
int iSize;
while (true)
{
aSocketList_Temp = (ArrayList)(aSocketList.Clone());
Socket.Select(aSocketList_Temp, null, null, -1);
foreach (Socket Temp in aSocketList_Temp)
{
if (Temp != aSocket)
{
iSize = Temp.Receive(aData);
aString = Temp.RemoteEndPoint +" : "+Encoding.Default.GetString(aData, 0, iSize);
if ("quit" != aString)
{
SendTOClient(Temp,aData, iSize);
Console.WriteLine("대화:" + aString);
}
else
{
string TempMessage = "채팅종료 : "+" : "+Temp.RemoteEndPoint;
Temp.Close();
aSocketList.Remove(Temp);
byte[] aData_Temp = Encoding.Default.GetBytes(TempMessage);
SendTOClient(aData_Temp, aData_Temp.Length);
Console.WriteLine(TempMessage);
Console.WriteLine("현재 접속자 수 : " + (aSocketList.Count - 1));
}
}
else
{
aSocketList.Add(Temp.Accept());
Console.WriteLine("새로운 접속자 : " + ((Socket)aSocketList[aSocketList.Count - 1]).RemoteEndPoint);
Console.WriteLine("현재 접속자 수 : " + (aSocketList.Count - 1));
}
}
}
}
public void Run()
{
byte[] aData;
string aString;
Console.WriteLine("Server Start...");
aThread.Start();
while (true)
{
Console.Write("서버 입력 : ");
aString = Console.ReadLine();
aData = Encoding.Default.GetBytes("[공지사항]" + aString);
//aData = Encoding.UTF8.GetBytes("[공지사항]" + aString); // 뿌띠 테스트용
SendTOClient(aData, aData.Length);
if ("quit" == aString)
{
break;
}
}
aThread.Abort();
foreach (Socket User in aSocketList)
{
User.Close();
}
aThread = null;
aSocket = null;
aSocketList = null;
}
}
class Program
{
static void Main(string[] args)
{
SmartServer aSmartServer = new SmartServer();
aSmartServer.Run();
}
}
}
클라이언트
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace NetSocket_client
{
class SmartClient
{
private Socket aSocket;
private string IP;
private int Port;
private Thread aThread;
private string NickName;
public SmartClient() : this("192.168.0.110",5000,"someone")
{
}
public SmartClient(string IP) : this(IP, 5000, "someone")
{
}
public SmartClient(int Port) : this("192.168.0.110", Port, "someone")
{
}
public SmartClient(string IP, int Port) : this(IP, Port, "someone")
{
}
public SmartClient(string IP, int Port, string NickName)
{
this.aSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
this.IP = IP;
this.Port = Port;
this.NickName = NickName;
aThread = new Thread(Receiver);
Console.WriteLine("서버 접속정보 : " + this.IP +" , "+ this.Port);
}
private void Receiver()
{
byte[] aData = new byte[1024];
string aString;
int iSize;
while (true)
{
iSize = aSocket.Receive(aData);
aString = Encoding.Default.GetString(aData, 0, iSize);
if (aString == "[공지사항]quit")
{
Console.WriteLine("서버의 종료 요청으로 채팅프로그램을 닫습니다.");
Environment.Exit(1); // .. 0은 시스템이 정상 종료를 알려준다.
}
Console.WriteLine("수신: " + aString);
}
}
public void run()
{
byte[] aData;
String aStirng;
Console.WriteLine("서버 접속 시도 중...");
aSocket.Connect("192.168.0.110", 5000);
Console.WriteLine("서버 온라인...");
aThread.Start();
while (true)
{
Console.Write("클라이언트 입력 : ");
aStirng = Console.ReadLine();
aData = Encoding.Default.GetBytes(aStirng);
aSocket.Send(aData,0, aData.Length, SocketFlags.None);
if ("quit" == aStirng)
{
aData = Encoding.Default.GetBytes("1명 나가유");
break;
}
}
aThread.Abort(); // Thread 가 무한 while 문이라서 join 은 쓸수 없다.
aSocket.Close();
}
}
class Program
{
static void Main(string[] args)
{
SmartClient client = new SmartClient();
client.run();
}
}
}
에러 처리 완료 코드
서버
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace NetSocket_210819_010
{
class SmartServer
{
private Thread aThread;
private Socket aSocket;
private ArrayList aSocketList;
private string IP;
private int Port;
private Dictionary<Socket, string> NicName;
public SmartServer() : this("192.168.0.110", 5000)
{
}
public SmartServer(string IP) : this(IP, 5000)
{
}
public SmartServer(int Port) : this("192.168.0.110", Port)
{
}
public SmartServer(string IP, int Port)
{
this.IP = IP;
this.Port = Port;
this.aSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
this.aSocket.Bind(new IPEndPoint(IPAddress.Parse(this.IP), this.Port));
}
catch (SocketException)
{
Console.WriteLine("Bind에 문제가 있어 서버 초기화가 불가능 합니다.");
aThread = null;
aSocket = null;
aSocketList = null;
IP = null;
Port = 0;
NicName = null;
return;
}
this.aSocket.Listen(5);
this.aSocketList = new ArrayList();
this.aSocketList.Add(aSocket);
aThread = new Thread(Receiver);
NicName = new Dictionary<Socket, string>();
NicName.Add(aSocket, "서버");
}
private void SendToClient(byte[] aData, int iSize)
{
foreach (Socket User in aSocketList)
{
if (User == aSocket)
{
continue;
}
User.Send(aData, 0, iSize, SocketFlags.None);
}
}
private void Receiver()
{
ArrayList aSocketList_Temp;
string aString;
byte[] aData = new byte[1024];
byte[] aData_Temp;
int iSize;
while (true)
{
aSocketList_Temp = (ArrayList)(aSocketList.Clone());
Socket.Select(aSocketList_Temp, null, null, -1);
foreach (Socket Temp in aSocketList_Temp)
{
if (Temp != aSocket)
{
try
{
iSize = Temp.Receive(aData);
aString = Encoding.Default.GetString(aData, 0, iSize);
}
catch (SocketException)
{
Console.WriteLine(NicName[Temp] + " 사용자와의 연결에 문제가 발생하였습니다.");
aString = "quit";
}
if ("quit" != aString)
{
aString = NicName[Temp] + " : " + aString;
aData_Temp = Encoding.Default.GetBytes(aString);
SendToClient(aData_Temp, aData_Temp.Length);
Console.WriteLine(aString);
}
else
{
aString = "\n" + NicName[Temp] + ": 채팅 종료\n";
Temp.Close();
aSocketList.Remove(Temp);
NicName.Remove(Temp);
aData_Temp = Encoding.Default.GetBytes(aString);
SendToClient(aData_Temp, aData_Temp.Length);
Console.WriteLine(aString);
Console.WriteLine("현재 접속자 수 : " + (aSocketList.Count - 1));
}
}
else
{
Socket aSocket = Temp.Accept();
iSize = aSocket.Receive(aData);
aString = Encoding.Default.GetString(aData, 0, iSize);
NicName.Add(aSocket, aString);
aSocketList.Add(aSocket);
Console.WriteLine("새로운 접속자(" + aSocket.RemoteEndPoint + ") : " + aString);
Console.WriteLine("현재 접속자 수 : " + (aSocketList.Count - 1));
}
}
}
}
public void Run()
{
byte[] aData;
string aString;
if (aSocket == null)
{
Console.WriteLine("서버가 초기화 되지 않아 실행이 불가합니다...");
return;
}
Console.WriteLine("Server Start...");
aThread.Start();
while (true)
{
Console.Write("서버 입력 : ");
aString = Console.ReadLine();
aData = Encoding.Default.GetBytes("[공지사항]" + aString);
//aData = Encoding.UTF8.GetBytes("[공지사항]" + aString); // 뿌띠 테스트용
SendToClient(aData, aData.Length);
if ("quit" == aString)
{
break;
}
}
aThread.Abort();
foreach (Socket User in aSocketList)
{
User.Close();
}
aThread = null;
aSocket = null;
NicName = null;
aSocketList = null;
}
}
class Program
{
static void Main(string[] args)
{
SmartServer aSmartServer = new SmartServer();
aSmartServer.Run();
}
}
}
클라이언트
using System;
using System.Linq.Expressions;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace NetSocket_Client_010
{
class SmartClient
{
private Socket aSocket;
private string IP;
private int Port;
private Thread aThread;
private Thread aThread2;
private bool bExit;
public SmartClient() : this("192.168.0.110", 5000)
{
}
public SmartClient(string IP) : this(IP, 5000)
{
}
public SmartClient(int Port) : this("192.168.0.110", Port)
{
}
public SmartClient(string IP, int Port)
{
aSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
this.IP = IP;
this.Port = Port;
this.bExit = false;
this.aThread = new Thread(Receiver);
this.aThread2 = new Thread(Sender);
Console.WriteLine("서버 접속 정보 : " + this.IP + ":" + this.Port);
}
private void Receiver()
{
byte[] aData = new byte[1024];
string aString;
int iSize;
while (true)
{
try
{
iSize = aSocket.Receive(aData);
aString = Encoding.Default.GetString(aData, 0, iSize);
}
catch (SocketException)
{
aString = "[공지사항]quit";
}
if (aString == "[공지사항]quit")
{
Console.WriteLine("서버의 종료 요청으로 채팅 프로그램을 닫습니다.");
bExit = true;
return;
}
Console.WriteLine("\n" + aString);
}
}
private void Sender()
{
byte[] aData;
string aString;
while (true)
{
Console.Write("> ");
aString = Console.ReadLine();
aData = Encoding.Default.GetBytes(aString);
aSocket.Send(aData, aData.Length, SocketFlags.None);
if ("quit" == aString)
{
bExit = true;
break;
}
}
}
public void Run()
{
byte[] aData;
string aString;
while (true)
{
Console.Write("닉네임을 입력하세요 : ");
aString = Console.ReadLine();
if (aString.Length == 0)
{
Console.WriteLine("잘 못된 닉네임입니다.");
continue;
}
break;
}
aString = "[" + aString + "]";
Console.WriteLine("서버 접속 시도 중...");
try
{
aSocket.Connect("192.168.0.110", 5000);
}
catch (SocketException)
{
Console.WriteLine("서버 오프라인...");
return;
}
aData = Encoding.Default.GetBytes(aString);
aSocket.Send(aData, aData.Length, SocketFlags.None);
Console.WriteLine("서버 온라인...");
aThread.Start();
aThread2.Start();
while (!bExit)
{
Thread.Sleep(10);
}
aThread.Abort();
aThread2.Abort();
aSocket.Close();
}
}
class Program
{
static void Main(string[] args)
{
SmartClient aSmartClient = new SmartClient();
aSmartClient.Run();
}
}
}
'공부,일 > C# 네트워크' 카테고리의 다른 글
packet 분석기 만들기 (3) (0) | 2021.09.15 |
---|---|
packet 분석기 만들기 (2) HexaViewer , NIC 선택 (0) | 2021.09.10 |
packet 분석기 만들기 (1) (0) | 2021.09.10 |
1:1 채팅 만들기 socket (0) | 2021.08.17 |
210817 쓰레드 (0) | 2021.08.17 |
댓글