C\#.NET 에서 Socket 간단 하고 실 용적 인 프레임 워 크 사용 튜 토리 얼
Socket 하면 모두 가 어느 정도 관련 이 있 을 것 입 니 다.최초의 컴퓨터 네트워크 과정 에서 tcp 프로 토 콜 을 이 야 기 했 고 Socket 은 프로 토 콜 에 대한 진일보 한 패키지 로 우리 개발 자 들 이 소프트웨어 간 의 통신 을 더욱 쉽게 할 수 있 도록 합 니 다.
이번 주 에 마침 차 의 자 물 쇠 를 공유 하 는 프로젝트 를 받 았 습 니 다.Socket 과 하드웨어 를 사용 하여 통신 통 제 를 해 야 합 니 다.즉,자물쇠 에 명령 을 보 내 고 열 리 거나 닫 히 는 것 을 제어 하 는 것 입 니 다.그리고 App 에 조작 인 터 페 이 스 를 개방 하여 테스트 와 사용자 의 사용 을 편리 하 게 해 야 합 니 다.그 중에서 핵심 은 바로 Socket 의 사용 이다.이 기능 을 개발 한 후에 저 는 사용 하기에 매우 불편 하 다 는 것 을 알 게 되 었 습 니 다.그래서 2 일 동안 그 핵심 기능 을 추상 화하 고 프레임 워 크 로 포장 한 다음 에 이 프레임 워 크 를 사용 하여 원래 의 프로젝트 를 재 구성 하고 출시 하여 소프트웨어 의 확장 성,건장 성,용 착 률 을 크게 향상 시 켰 습 니 다.
개인 이 굳 게 믿 는 원칙:만물 은 모두 대상 이다.
자,잔말 말고 본문 으로 들 어가 세 요.
본문:
1.먼저 C\#중 Socket 의 간단 한 사용 에 대해 간단히 설명 합 니 다.
첫 번 째 단계:서버 에서 어떤 포트 를 감청 합 니 다.
두 번 째 단계:클 라 이언 트 가 서버 주소 와 포트 에 Socket 연결 요청 을 합 니 다.
세 번 째 단계:서버 에서 연결 요청 을 받 은 후 Socket 연결 을 만 들 고 이 연결 대기 열 을 유지 합 니 다.
네 번 째 단계:클 라 이언 트 와 서비스 사 이 드 는 쌍 공 통신(즉,양 방향 통신)을 구축 하여 클 라 이언 트 와 서비스 사 이 드 는 서로 에 게 쉽게 정 보 를 보 낼 수 있다.
간단하게 사용 하 는 구체 적 인 실현 코드 는 모두 제 가 프로젝트 에 포 장 했 습 니 다.만약 에 간단 한 실현 을 배 워 야 한다 면 제 소스 코드 를 볼 수 있 고 바 이 두 도 할 수 있 습 니 다.많은 튜 토리 얼 이 있 습 니 다.
2.핵심,프레임 의 사용
사실 틀 이 라 고 하기 에는 무리 가 있 을 수 있 습 니 다.모든 사람 이 틀 에 대해 자신 만 의 이 해 를 가지 고 있 기 때 문 입 니 다.그러나 라 이브 러 리 와 틀 은 어떤 본질 적 인 차이 가 있 습 니까?모두 코드~하하,멀 어 졌어
우선,근거 없 이 모든 코드 를 놓 습 니 다.
서버 원본 파일:
SocketServer.cs
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
namespace Coldairarrow.Util.Sockets
{
/// <summary>
/// Socket
/// </summary>
public class SocketServer
{
#region
/// <summary>
///
/// </summary>
/// <param name="ip"> IP </param>
/// <param name="port"> </param>
public SocketServer(string ip, int port)
{
_ip = ip;
_port = port;
}
/// <summary>
/// , IP 0.0.0.0
/// </summary>
/// <param name="port"> </param>
public SocketServer(int port)
{
_ip = "0.0.0.0";
_port = port;
}
#endregion
#region
private Socket _socket = null;
private string _ip = "";
private int _port = 0;
private bool _isListen = true;
private void StartListen()
{
try
{
_socket.BeginAccept(asyncResult =>
{
try
{
Socket newSocket = _socket.EndAccept(asyncResult);
// ,
if (_isListen)
StartListen();
SocketConnection newClient = new SocketConnection(newSocket, this)
{
HandleRecMsg = HandleRecMsg == null ? null : new Action<byte[], SocketConnection, SocketServer>(HandleRecMsg),
HandleClientClose = HandleClientClose == null ? null : new Action<SocketConnection, SocketServer>(HandleClientClose),
HandleSendMsg = HandleSendMsg == null ? null : new Action<byte[], SocketConnection, SocketServer>(HandleSendMsg),
HandleException = HandleException == null ? null : new Action<Exception>(HandleException)
};
newClient.StartRecMsg();
ClientList.AddLast(newClient);
HandleNewClientConnected?.Invoke(this, newClient);
}
catch (Exception ex)
{
HandleException?.Invoke(ex);
}
}, null);
}
catch (Exception ex)
{
HandleException?.Invoke(ex);
}
}
#endregion
#region
/// <summary>
/// ,
/// </summary>
public void StartServer()
{
try
{
// (ip4 , ,TCP )
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// ip
IPAddress address = IPAddress.Parse(_ip);
// ip port
IPEndPoint endpoint = new IPEndPoint(address, _port);
// IP
_socket.Bind(endpoint);
// Int32 ( )
_socket.Listen(int.MaxValue);
//
StartListen();
HandleServerStarted?.Invoke(this);
}
catch (Exception ex)
{
HandleException?.Invoke(ex);
}
}
/// <summary>
///
/// </summary>
public LinkedList<SocketConnection> ClientList { get; set; } = new LinkedList<SocketConnection>();
/// <summary>
///
/// </summary>
/// <param name="theClient"> </param>
public void CloseClient(SocketConnection theClient)
{
theClient.Close();
}
#endregion
#region
/// <summary>
///
/// </summary>
public Action<Exception> HandleException { get; set; }
#endregion
#region
/// <summary>
///
/// </summary>
public Action<SocketServer> HandleServerStarted { get; set; }
/// <summary>
///
/// </summary>
public Action<SocketServer, SocketConnection> HandleNewClientConnected { get; set; }
/// <summary>
///
/// </summary>
public Action<SocketServer, SocketConnection> HandleCloseClient { get; set; }
#endregion
#region
/// <summary>
///
/// </summary>
public Action<byte[], SocketConnection, SocketServer> HandleRecMsg { get; set; }
/// <summary>
///
/// </summary>
public Action<byte[], SocketConnection, SocketServer> HandleSendMsg { get; set; }
/// <summary>
///
/// </summary>
public Action<SocketConnection, SocketServer> HandleClientClose { get; set; }
#endregion
}
}
using System;
using System.Net.Sockets;
using System.Text;
namespace Coldairarrow.Util.Sockets
{
/// <summary>
/// Socket ,
/// </summary>
public class SocketConnection
{
#region
public SocketConnection(Socket socket,SocketServer server)
{
_socket = socket;
_server = server;
}
#endregion
#region
private readonly Socket _socket;
private bool _isRec=true;
private SocketServer _server = null;
private bool IsSocketConnected()
{
bool part1 = _socket.Poll(1000, SelectMode.SelectRead);
bool part2 = (_socket.Available == 0);
if (part1 && part2)
return false;
else
return true;
}
#endregion
#region
/// <summary>
///
/// </summary>
public void StartRecMsg()
{
try
{
byte[] container = new byte[1024 * 1024 * 2];
_socket.BeginReceive(container, 0, container.Length, SocketFlags.None, asyncResult =>
{
try
{
int length = _socket.EndReceive(asyncResult);
// ,
if (length > 0 && _isRec && IsSocketConnected())
StartRecMsg();
if (length > 0)
{
byte[] recBytes = new byte[length];
Array.Copy(container, 0, recBytes, 0, length);
//
HandleRecMsg?.Invoke(recBytes, this, _server);
}
else
Close();
}
catch (Exception ex)
{
HandleException?.Invoke(ex);
Close();
}
}, null);
}
catch (Exception ex)
{
HandleException?.Invoke(ex);
Close();
}
}
/// <summary>
///
/// </summary>
/// <param name="bytes"> </param>
public void Send(byte[] bytes)
{
try
{
_socket.BeginSend(bytes, 0, bytes.Length, SocketFlags.None, asyncResult =>
{
try
{
int length = _socket.EndSend(asyncResult);
HandleSendMsg?.Invoke(bytes, this, _server);
}
catch (Exception ex)
{
HandleException?.Invoke(ex);
}
}, null);
}
catch (Exception ex)
{
HandleException?.Invoke(ex);
}
}
/// <summary>
/// ( UTF-8 )
/// </summary>
/// <param name="msgStr"> </param>
public void Send(string msgStr)
{
Send(Encoding.UTF8.GetBytes(msgStr));
}
/// <summary>
/// ( )
/// </summary>
/// <param name="msgStr"> </param>
/// <param name="encoding"> </param>
public void Send(string msgStr,Encoding encoding)
{
Send(encoding.GetBytes(msgStr));
}
/// <summary>
///
/// </summary>
public object Property { get; set; }
/// <summary>
///
/// </summary>
public void Close()
{
try
{
_isRec = false;
_socket.Disconnect(false);
_server.ClientList.Remove(this);
HandleClientClose?.Invoke(this, _server);
_socket.Close();
_socket.Dispose();
GC.Collect();
}
catch (Exception ex)
{
HandleException?.Invoke(ex);
}
}
#endregion
#region
/// <summary>
///
/// </summary>
public Action<byte[], SocketConnection, SocketServer> HandleRecMsg { get; set; }
/// <summary>
///
/// </summary>
public Action<byte[], SocketConnection, SocketServer> HandleSendMsg { get; set; }
/// <summary>
///
/// </summary>
public Action<SocketConnection, SocketServer> HandleClientClose { get; set; }
/// <summary>
///
/// </summary>
public Action<Exception> HandleException { get; set; }
#endregion
}
}
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace Coldairarrow.Util.Sockets
{
/// <summary>
/// Socket
/// </summary>
public class SocketClient
{
#region
/// <summary>
/// , IP 127.0.0.1
/// </summary>
/// <param name="port"> </param>
public SocketClient(int port)
{
_ip = "127.0.0.1";
_port = port;
}
/// <summary>
///
/// </summary>
/// <param name="ip"> IP </param>
/// <param name="port"> </param>
public SocketClient(string ip, int port)
{
_ip = ip;
_port = port;
}
#endregion
#region
private Socket _socket = null;
private string _ip = "";
private int _port = 0;
private bool _isRec=true;
private bool IsSocketConnected()
{
bool part1 = _socket.Poll(1000, SelectMode.SelectRead);
bool part2 = (_socket.Available == 0);
if (part1 && part2)
return false;
else
return true;
}
/// <summary>
///
/// </summary>
public void StartRecMsg()
{
try
{
byte[] container = new byte[1024 * 1024 * 2];
_socket.BeginReceive(container, 0, container.Length, SocketFlags.None, asyncResult =>
{
try
{
int length = _socket.EndReceive(asyncResult);
// ,
if (length > 0 && _isRec && IsSocketConnected())
StartRecMsg();
if (length > 0)
{
byte[] recBytes = new byte[length];
Array.Copy(container, 0, recBytes, 0, length);
//
HandleRecMsg?.Invoke(recBytes, this);
}
else
Close();
}
catch (Exception ex)
{
HandleException?.Invoke(ex);
Close();
}
}, null);
}
catch (Exception ex)
{
HandleException?.Invoke(ex);
Close();
}
}
#endregion
#region
/// <summary>
/// ,
/// </summary>
public void StartClient()
{
try
{
// (ip4 , ,TCP )
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// ip
IPAddress address = IPAddress.Parse(_ip);
// ip port
IPEndPoint endpoint = new IPEndPoint(address, _port);
// IP
_socket.BeginConnect(endpoint, asyncResult =>
{
try
{
_socket.EndConnect(asyncResult);
//
StartRecMsg();
HandleClientStarted?.Invoke(this);
}
catch (Exception ex)
{
HandleException?.Invoke(ex);
}
}, null);
}
catch (Exception ex)
{
HandleException?.Invoke(ex);
}
}
/// <summary>
///
/// </summary>
/// <param name="bytes"> </param>
public void Send(byte[] bytes)
{
try
{
_socket.BeginSend(bytes, 0, bytes.Length, SocketFlags.None, asyncResult =>
{
try
{
int length = _socket.EndSend(asyncResult);
HandleSendMsg?.Invoke(bytes, this);
}
catch (Exception ex)
{
HandleException?.Invoke(ex);
}
}, null);
}
catch (Exception ex)
{
HandleException?.Invoke(ex);
}
}
/// <summary>
/// ( UTF-8 )
/// </summary>
/// <param name="msgStr"> </param>
public void Send(string msgStr)
{
Send(Encoding.UTF8.GetBytes(msgStr));
}
/// <summary>
/// ( )
/// </summary>
/// <param name="msgStr"> </param>
/// <param name="encoding"> </param>
public void Send(string msgStr, Encoding encoding)
{
Send(encoding.GetBytes(msgStr));
}
/// <summary>
///
/// </summary>
public object Property { get; set; }
/// <summary>
///
/// </summary>
public void Close()
{
try
{
_isRec = false;
_socket.Disconnect(false);
HandleClientClose?.Invoke(this);
}
catch (Exception ex)
{
HandleException?.Invoke(ex);
}
}
#endregion
#region
/// <summary>
///
/// </summary>
public Action<SocketClient> HandleClientStarted { get; set; }
/// <summary>
///
/// </summary>
public Action<byte[], SocketClient> HandleRecMsg { get; set; }
/// <summary>
///
/// </summary>
public Action<byte[], SocketClient> HandleSendMsg { get; set; }
/// <summary>
///
/// </summary>
public Action<SocketClient> HandleClientClose { get; set; }
/// <summary>
///
/// </summary>
public Action<Exception> HandleException { get; set; }
#endregion
}
}위 에 놓 인 것 은 프레임 코드 입 니 다.다음은 어떻게 사용 하 는 지 소개 하 겠 습 니 다.우선,서버 사용 방식:
using Coldairarrow.Util.Sockets;
using System;
using System.Text;
namespace Console_Server
{
class Program
{
static void Main(string[] args)
{
// , 0.0.0.0, 12345
SocketServer server = new SocketServer(12345);
//
server.HandleRecMsg = new Action<byte[], SocketConnection, SocketServer>((bytes, client, theServer) =>
{
string msg = Encoding.UTF8.GetString(bytes);
Console.WriteLine($" :{msg}");
});
//
server.HandleServerStarted = new Action<SocketServer>(theServer =>
{
Console.WriteLine(" ************");
});
//
server.HandleNewClientConnected = new Action<SocketServer, SocketConnection>((theServer, theCon) =>
{
Console.WriteLine($@" , :{theServer.ClientList.Count}");
});
//
server.HandleClientClose = new Action<SocketConnection, SocketServer>((theCon, theServer) =>
{
Console.WriteLine($@" , :{theServer.ClientList.Count}");
});
//
server.HandleException = new Action<Exception>(ex =>
{
Console.WriteLine(ex.Message);
});
//
server.StartServer();
while (true)
{
Console.WriteLine(" :quit, ");
string op = Console.ReadLine();
if (op == "quit")
break;
}
}
}
}클 라 이언 트 사용 방법:
using Coldairarrow.Util.Sockets;
using System;
using System.Text;
namespace Console_Client
{
class Program
{
static void Main(string[] args)
{
// , 127.0.0.1, 12345
SocketClient client = new SocketClient(12345);
//
client.HandleRecMsg = new Action<byte[], SocketClient>((bytes, theClient) =>
{
string msg = Encoding.UTF8.GetString(bytes);
Console.WriteLine($" :{msg}");
});
//
client.HandleSendMsg = new Action<byte[], SocketClient>((bytes, theClient) =>
{
string msg = Encoding.UTF8.GetString(bytes);
Console.WriteLine($" :{msg}");
});
//
client.StartClient();
while (true)
{
Console.WriteLine(" :quit , ");
string str = Console.ReadLine();
if (str == "quit")
{
client.Close();
break;
}
else
{
client.Send(str);
}
}
}
}
}마지막 으로 테스트 캡 처 실행:
요약:
가장 편리 한 점 은 연결 패 키 징 을 만 드 는 방법 입 니 다.사용 자 는 연결 후 어떤 데 이 터 를 보 내 는 지,데 이 터 를 받 은 후에 어떻게 처리 해 야 하 는 지 등 다른 많은 사건 의 처 리 를 주목 해 야 합 니 다.그 중에서 익명 의뢰 의 사용,Lambda 표현 식 의 사용 에 의존 합 니 다.
프레임 안에 주로 비동기 통신 을 사 용 했 고 연결 을 어떻게 통제 하 는 지 상세 하 게 말씀 드 리 지 않 겠 습 니 다.여러분 들 은 한 번 보면 알 수 있 을 것 입 니 다.저 는 여러분 에 게 편 의 를 가 져 다 주 고 싶 을 뿐 입 니 다.
자,이상 이 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
마지막 으로 모든 소스 항목 주 소 를 동봉 합 니 다.어느 정도 가치 가 있다 고 생각 되면 좋아요 도 눌 러 주세요~
GitHub 주소:https://github.com/Coldairarrow/Sockets
로 컬 다운로드:http://xiazai.jb51.net/201709/yuanma/Sockets(jb51.net).rar
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C#Task를 사용하여 비동기식 작업을 수행하는 방법라인이 완성된 후에 이 라인을 다시 시작할 수 없습니다.반대로 조인(Join)만 결합할 수 있습니다 (프로세스가 현재 라인을 막습니다). 임무는 조합할 수 있는 것이다. 연장을 사용하여 그것들을 한데 연결시키는 것이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.