C\#윈도 서비스 기반 채 팅 프로그램(1)
간단 한 메 시 지 는 서버 를 통 해 전달 되 고 파일 류 의 메 시 지 는 클 라 이언 트 가 스스로 연결 을 만들어 전송 합 니 다.후속 기능 은 천천히 완 선 될 것 이다.
사용자 정의 프로 토 콜:
1.새 Windows 서비스 항목
2.프로필 수정 추가
<appSettings>
<add key="maxQueueCount" value="10"/>
<add key="failoverServer" value="192.168.250.113,192.168.250.141"/>
</appSettings>
설명:max QueueCount 는 최대 연결 수 이 며,failoverServer 고장 으로 예비 서버(여러 서버,분리)를 옮 깁 니 다.3.ChatService 오른쪽 단 추 를 누 르 면 설치 프로그램 이 추 가 됩 니 다.이 때 ProjectInstaller.cs 파일 이 자동 으로 추 가 됩 니 다.파일 에 기본적으로 serviceProcessInstaller 1 과 serviceInstaller 1 두 구성 요 소 를 추가 합 니 다.
serviceInstaller 1 과 serviceProcessInstaller 1 의 속성 정 보 를 수정 합 니 다.그림 참조
StartType 속성 설명:
Automatic 지시 서 비 스 는 시스템 이 시 작 될 때(또는 이미)운영 체제 에서 시 작 됩 니 다.자동 으로 시작 되 는 서비스 가 수 동 으로 시작 되 는 서비스 에 의존 하면 수 동 으로 시작 되 는 서비스 도 시스템 이 시 작 될 때 자동 으로 시 작 됩 니 다.
Disabled 는 사용자 나 프로그램 에서 시작 할 수 없 도록 이 서 비 스 를 사용 하지 않 으 라 고 지시 합 니 다.
Manual 지시 서 비 스 는 사용자("서비스 제어 관리자"사용)나 응용 프로그램 에서 만 수 동 으로 시 작 됩 니 다.
계 정 속성 설명:
LocalService 로 컬 컴퓨터 의 비 특권 사용자 계 정 으로 이 계 정 은 익명 의 증 거 를 모든 원 격 서버 에 제공 합 니 다.
LocalSystem 서비스 제어 관리자 가 사용 하 는 계 정 은 로 컬 컴퓨터 의 많은 권한 을 가지 고 네트워크 의 컴퓨터 로 사용 된다.
NetworkService 광범 위 한 로 컬 특권 을 가 진 계 정 을 제공 합 니 다.이 계 정 은 컴퓨터 의 증 거 를 모든 원 격 서버 에 제공 합 니 다.
User 네트워크 상에 서 특정한 사용자 가 정의 하 는 계 정.ServiceProcessInstaller.Account 구성원 에 게 user 를 지정 하면 시스템 이 서 비 스 를 설치 할 때 올 바른 사용자 이름과 비밀 번 호 를 입력 하 는 것 을 알려 줍 니 다.ServiceProcessInstaller 인 스 턴 스 의 Username 과 Password 라 는 두 속성 설정 값 을 입력 하지 않 는 한.
4.완료 후 ChatService 코드 를 열 고 OnStart 와 OnStop 방법(즉,서비스의 시작 과 정지 방법)을 다시 씁 니 다.다른 방법 을 다시 쓰 려 면 ServiceBase 에서 보십시오.
5.프로젝트 에 서비스 등록 과 스 크 립 트 파일 마 운 트 해제 추가
Install.bat
@echo off
path %SystemRoot%\Microsoft.NET\Framework\v4.0.30319;%path%
installutil %~dp0\WindowsChat.exe
%SystemRoot%\system32\sc failure "ChatService" reset= 30 actions= restart/1000
pause
@echo on
Uninstall.bat
@echo off
path %SystemRoot%\Microsoft.NET\Framework\v4.0.30319;%path%
installutil -u %~dp0\WindowsChat.exe
pause
@echo on
설명:%~dp0 은 bat 파일 이 있 는 디 렉 터 리 를 표시 합 니 다.파일 속성 선택 시종 복사-내용,그래 야 출력 폴 더 에 생 성 됩 니 다.
6.위 에 있 는 OnStart 와 OnStop 재 작성 방법 으로 돌아 가기
SocketHelper 클래스 만 들 기
namespace WindowsChat
{
public delegate void WriteInfo(string info);
public class SocketHelper
{
#region
public SocketHelper()
{
}
public SocketHelper(WriteInfo method)
{
this.method = method;
}
#endregion
public static Socket LocalSocket = null;
private object lockObj = new object();
public static List<Socket> Clients = new List<Socket>();
private WriteInfo method = null;
/// <summary>
/// Socket
/// </summary>
/// <param name="port"> 11011</param>
/// <param name="backlog">The maximum length of the pending connections queue.</param>
/// <returns></returns>
public Socket Create(int port = 11011, int backlog = 100)
{
if (LocalSocket == null)
{
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, port);// IP
LocalSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
LocalSocket.Bind(ipEndPoint);
LocalSocket.Listen(backlog);
}
return LocalSocket;
}
/// <summary>
///
/// </summary>
/// <param name="id"> </param>
/// <returns></returns>
private Socket FindLinked(string id)
{
foreach (var item in Clients)
{
if (item.RemoteEndPoint.ToString() == id)
return item;
}
return null;
}
/// <summary>
///
/// </summary>
public void Accept()
{
if (LocalSocket != null)
{
while (true)
{
Socket client = LocalSocket.Accept();
Thread thread = new Thread(new ParameterizedThreadStart(Revice));
thread.Start(client);
WriteLog(" :" + client.RemoteEndPoint.ToString() + " ");
lock (lockObj)
{
Clients.Add(client);
}
BroadCast("ADD|" + client.RemoteEndPoint.ToString());
}
}
}
/// <summary>
///
/// </summary>
/// <param name="info"> </param>
private void WriteLog(string info)
{
using (FileStream fs = new FileStream("C:\\chatservice.txt", FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
{
using (StreamWriter sw = new StreamWriter(fs, Encoding.UTF8))
{
sw.WriteLine(info);
}
}
if (method != null)
{
method(info);
}
}
/// <summary>
///
/// </summary>
/// <param name="info"> </param>
public void BroadCast(string info)
{
foreach (var item in Clients)
{
try
{
item.Send(Encoding.UTF8.GetBytes(info));
}
catch (Exception ex)
{
WriteLog(item.RemoteEndPoint.ToString() + ex.Message);
continue;
}
}
}
/// <summary>
///
/// </summary>
/// <param name="client"></param>
public void Revice(object client)
{
Socket param = client as Socket;
var remoteName = param.RemoteEndPoint.ToString();
if (param != null)
{
int res = 0;
while (true)
{
byte[] buffer = new byte[10240];
int size = param.ReceiveBufferSize;
try
{
res = param.Receive(buffer);
}
catch (SocketException ex)
{
if (ex.SocketErrorCode == SocketError.ConnectionReset)
{
Clients.Remove(param);
WriteLog(" :" + remoteName + " 1");
BroadCast("REMOVE|" + remoteName);
param.Close();
return;
}
}
if (res == 0)
{
Clients.Remove(param);
WriteLog(" :" + remoteName + " 2");
BroadCast("REMOVE|" + remoteName);
param.Close();
return;
}
var clientMsg = Encoding.UTF8.GetString(buffer, 0, res);
WriteLog(string.Format(" {0} :{1}", remoteName, clientMsg));
if (clientMsg == "GETALL")
{
StringBuilder sb = new StringBuilder();
foreach (var item in Clients)
{
sb.AppendFormat("{0}|", item.RemoteEndPoint.ToString());
}
param.Send(Encoding.UTF8.GetBytes("ALL|" + sb.ToString()));
}
else if (clientMsg == "OFFLINE")
{
if (Clients.Contains(param))
{
Clients.Remove(param);
WriteLog(" :" + remoteName + " 2");
BroadCast("REMOVE|" + remoteName);
param.Close();
return;
}
}
else if (clientMsg.StartsWith("TRANST|"))
{
var msgs = clientMsg.Split('|');
var toSocket = FindLinked(msgs[1]);
if (toSocket != null)
{
WriteLog(remoteName + " " + msgs[1] + " " + msgs[2]);
toSocket.Send(Encoding.UTF8.GetBytes("TRANSF|" + remoteName + "|" + msgs[2]));
}
}
}
}
}
}
}
OnStart 와 OnStop 재 작성 방법
public partial class ChatService : ServiceBase
{
SocketHelper helper;
Thread mainThread;
public ChatService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
if (helper == null)
{
helper = new SocketHelper();
}
helper.Create();
mainThread = new Thread(new ThreadStart(helper.Accept));
mainThread.IsBackground = true;
mainThread.Start();
}
protected override void OnStop()
{
helper.BroadCast("SHUTDOWN");
}
}
이로써 간단 하고 쉬 운 윈도 서비스의 채 팅 서버 개발 이 완료 되 었 고 후속 적 으로 이 를 바탕 으로 확 대 될 것 이다.install.bat 실행(관리자 로 실행)그림 참조
7.services.msc 를 실행 하여 ChatService 서 비 스 를 찾 을 수 있 습 니 다.정상적으로 작 동 정지 설명 배치 성공!
물론 실행 파일 이 있 는 디 렉 터 리 에 InstallUtil.exe 를 복사 할 수도 있 습 니 다.예 를 들 어 c:\bin\
배포 스 크 립 트
cd c:\bin\
InstallUtil WindowsChat.exe
스 크 립 트 마 운 트 해제
InstallUtil -u WindowsChat.exe
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
WebView2를 Visual Studio 2017 Express에서 사용할 수 있을 때까지Evergreen .Net Framework SDK 4.8 VisualStudio2017에서 NuGet을 사용하기 때문에 패키지 관리 방법을 packages.config 대신 PackageReference를 사용해야...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.