本随笔提供了一个有用的Windows服务小程序的主要是Server端的Socket通信服务。本人也不是非常熟悉Windows服务和Socket通信的知识,但是经过了一天的不懈努力还是了解和学习了一些这方面的皮毛,还望知道这方面知识的博友不吝赐教。
今天被迫要做一个接收通信的模块,以前从来都没有做过关于通信方面的东西,就像没有做过有关GIS方面的程序一样是头一次开发此类程序。
这个Socket通信说是自己的其实完全不是(如果哪位高人见到此程序是您本人开发的千万不要介意,本人也是在网上搜索出的,这个程序真的很不错,值得推广哦!在此谢谢发布此Socket通信程序的高人)。
此程序的大部分源码没有任何改动,只是原来的Server端是用C/S程序写的,为了能使Socket通信的Server端更灵活,在此将其改成一个Windows服务,因此也需要改动了一些Server端的代码和工程,但是基础类和Client端都没有改变。
对于我本人来说,Windows服务和Socket通信本人都不是很了解,只是经过了昨天简单的学习和研究才完成了此Windows服务Server端Socket通信程序,所以也说不出太多的门道,如果有清楚这方面知识的博友还希望能多多交流。好了,废话少说,开始正题了。
现在开始我们来讲解,如何一步一步地完成Windows服务Server端Socket通信程序。
我个人认为Windows服务只是包裹在Socket通信程序外的“一件外套”,所以核心还是我在网上找到的这个Socket程序,为此我们的第一步应该先开发出此Socket程序的类库。
1、打开Visual Studio.Net2003,单击菜单中的“文件”——>“新建”——>“项目”,在弹出的对话框左侧选择“Visual C#项目”,在右侧选择“类库”,下方的名称中输入“SocketLibrary”,位置自己随便选择一个路径。
2、删除自动创建的Class1.cs,新建如下的类名文件“Client.cs”、“Connection.cs”、“ConnectionCollection.cs”、“Message.cs”、“MessageCollection.cs”、“Server.cs”、“SocketBase.cs”和“SocketFactory.cs”。
3、各个类文件的代码如下:
(1)、Client.cs文件中的代码:

Client.cs文件代码
using System;
using System.Net;
using System.Net.Sockets;

namespace SocketLibrary


{

public class Client:SocketBase

{
public const int CONNECTTIMEOUT = 10;
public Client()

{
}

public Connection StartClient(IPAddress ipaddress,int port)
{
TcpClient client = new TcpClient();
client.SendTimeout = CONNECTTIMEOUT;
client.ReceiveTimeout = CONNECTTIMEOUT;

client.Connect(ipaddress,port);

this._connections.Add(new Connection(client.GetStream()));
this.StartListenAndSend();
return new Connection(client.GetStream());
}

public void StopClient()
{

this.EndListenAndSend();
}
}
}
(2)、Connection.cs文件中的代码:

Connection.cs文件代码
using System;
using System.Net;
using System.Net.Sockets;

namespace SocketLibrary


{

/**//// <summary>
/// Connection 的摘要说明。
/// </summary>
public class Connection

{

public NetworkStream NetworkStream
{

get
{return _networkStream;}

set
{_networkStream = value;}
}
private NetworkStream _networkStream;

public string ConnectionName
{

get
{return _connectionName;}

set
{_connectionName = value;}
}
private string _connectionName;
public Connection(NetworkStream networkStream,string connectionName)

{
this._networkStream = networkStream;
this._connectionName = connectionName;
}

public Connection(NetworkStream networkStream):this(networkStream,string.Empty)
{
}
}
}
(3)、ConnectionCollection.cs文件中的代码:

ConnectionCollection.cs文件代码
using System;


namespace SocketLibrary
{

public class ConnectionCollection:System.Collections.CollectionBase
{

public ConnectionCollection()
{
}

public void Add(Connection value)
{
List.Add(value);
}

public Connection this[int index]
{

get
{
return List[index] as Connection;
}

set
{
List[index] = value;
}
}

public Connection this[string connectionName]
{

get
{

foreach(Connection connection in List)
{
if(connection.ConnectionName == connectionName)
return connection;
}
return null;
}
}
}
}
(4)、Message.cs文件中的代码:

Message.cs文件代码
using System;

namespace SocketLibrary


{
public class Message

{

public enum CommandHeader:byte
{
SendMessage = 1
}
public Connection SendToOrReceivedFrom;
public int MessageLength;
public CommandHeader Command;
public byte MainVersion;
public byte SecondVersion;

public string MessageBody;

public bool Sent;

public Message()

{
SendToOrReceivedFrom = null;
Sent = false;
}

public Message(CommandHeader command,byte mainVersion,byte secondVersion,string messageBody):this()
{
this.Command = command;
this.MainVersion = mainVersion;
this.SecondVersion = secondVersion;
this.MessageBody = messageBody;
}

public byte[] ToBytes()
{
this.MessageLength = 7 + SocketFactory.DefaultEncoding.GetByteCount(this.MessageBody);//计算消息总长度。消息头长度为7加上消息体的长度。
byte[] buffer = new byte[this.MessageLength];
//先将长度的4个字节写入到数组中。
BitConverter.GetBytes(this.MessageLength).CopyTo(buffer,0);
//将CommandHeader写入到数组中
buffer[4] = (byte)this.Command;
//将主版本号写入到数组中
buffer[5] = (byte)this.MainVersion;
//将次版本号写入到数组中
buffer[6] = (byte)this.SecondVersion;

//消息头已写完,现在写消息体。
byte[] body = new byte[this.MessageLength - 7];
SocketFactory.DefaultEncoding.GetBytes(this.MessageBody).CopyTo(buffer,7);
return buffer;
}

public static Message Parse(Connection connection)
{
Message message = new Message();
//先读出前四个字节,即Message长度
byte[] buffer = new byte[4];

if(connection.NetworkStream.DataAvailable)
{
int count = connection.NetworkStream.Read(buffer,0,4);

if(count == 4)
{
message.MessageLength = BitConverter.ToInt32(buffer,0);
}
else
throw new Exception("网络流长度不正确");
}
else
throw new Exception("目前网络不可读");
//读出消息的其它字节
buffer = new byte[message.MessageLength - 4];

if(connection.NetworkStream.DataAvailable)
{
int count = connection.NetworkStream.Read(buffer,0,buffer.Length);

if(count == message.MessageLength -4)
{
message.Command = (CommandHeader)buffer[0];
message.MainVersion = buffer[1];
message.SecondVersion = buffer[2];

//读出消息体
message.MessageBody = SocketFactory.DefaultEncoding.GetString(buffer,3,buffer.Length - 3);
message.SendToOrReceivedFrom = connection;

return message;
}
else
throw new Exception("网络流长度不正确");
}
else
throw new Exception("目前网络不可读");
}

}
}
(5)、MessageCollection.cs文件中的代码:

MessageCollection.cs文件代码
using System;

namespace SocketLibrary


{
public class MessageCollection:System.Collections.CollectionBase

{
public MessageCollection()

{
}

public void Add(Message value)
{
List.Add(value);
}

public Message this[int index]
{

get
{
return List[index] as Message;
}

set
{
List[index] = value;
}
}

public MessageCollection this[Connection connection]
{

get
{
MessageCollection collection = new MessageCollection();

foreach(Message message in List)
{
if(message.SendToOrReceivedFrom == connection)
collection.Add(message);
}
return collection;
}
}
}
}
(6)、Server.cs文件中的代码:

Server.cs文件代码
using System;
using System.Net;
using System.Net.Sockets;

namespace SocketLibrary


{
public class Server:SocketBase

{

private TcpListener _listener;
public Server()

{
this._connections = new ConnectionCollection();
}
protected System.Threading.Thread _listenConnection;


public void StartServer(int port)
{
_listener = new TcpListener(IPAddress.Any, port);
_listener.Start();

_listenConnection = new System.Threading.Thread(new System.Threading.ThreadStart(Start));
_listenConnection.Start();

this.StartListenAndSend();
}

public void StopServer()
{
_listenConnection.Abort();
this.EndListenAndSend();
}

private void Start()
{

try
{

while(true)
{

if(_listener.Pending())
{
TcpClient client = _listener.AcceptTcpClient();
NetworkStream stream = client.GetStream();
Connection connection = new Connection(stream);
this._connections.Add(connection);
this.OnConnected(this,new ConnectionEventArgs(connection,new Exception("连接成功")));
}
System.Threading.Thread.Sleep(200);
}
}

catch
{
}
}
}
}

(7)、SocketBase.cs文件中的代码:

SocketBase.cs文件代码
using System;

namespace SocketLibrary


{

/**//// <summary>
/// SocketBase 的摘要说明。
/// </summary>
public class SocketBase

{

public class MessageEventArgs:EventArgs
{
public Message Message;
public Connection Connecction;

public MessageEventArgs(Message message,Connection connection)
{
this.Message = message;
this.Connecction = connection;
}
}
public delegate void MessageEventHandler(object sender,MessageEventArgs e);


public class ConnectionEventArgs:EventArgs
{
public Connection Connection;
public Exception Exception;

public ConnectionEventArgs(Connection connection,Exception exception)
{
this.Connection = connection;
this.Exception = exception;
}
}
public delegate void ConnectionHandler(object sender,ConnectionEventArgs e);


public ConnectionCollection Connections
{

get
{return _connections;}

set
{_connections = value;}
}
protected ConnectionCollection _connections;


public MessageCollection messageQueue
{

get
{return _messageQueue;}

set
{_messageQueue = value;}
}
protected MessageCollection _messageQueue;

public SocketBase()

{
this._connections = new ConnectionCollection();
this._messageQueue = new MessageCollection();
}

protected void Send(Message message)
{
this.Send(message,message.SendToOrReceivedFrom);
}

protected void Send(Message message,Connection connection)
{
byte[] buffer = message.ToBytes();

lock(this)
{
connection.NetworkStream.Write(buffer,0,buffer.Length);
}
}

protected System.Threading.Thread _listenningthread;
protected System.Threading.Thread _sendthread;

protected virtual void Sendding()
{

try
{

while(true)
{
System.Threading.Thread.Sleep(200);

for(int i = 0 ; i < this.messageQueue.Count ; i++)
{

if(this.messageQueue[i].SendToOrReceivedFrom != null)
{
this.Send(this.messageQueue[i]);
this.OnMessageSent(this,new MessageEventArgs(this.messageQueue[i],this.messageQueue[i].SendToOrReceivedFrom));
}

else
{//对每一个连接都发送此消息

for(int j = 0 ; j < this.Connections.Count ; j++)
{
this.Send(this.messageQueue[i],this.Connections[j]);
this.OnMessageSent(this,new MessageEventArgs(this.messageQueue[i],this.Connections[j]));
}
}
this.messageQueue[i].Sent = true;
}
//清除所有已发送消息

for(int i = this.messageQueue.Count - 1 ; i > -1 ; i--)
{
if(this.messageQueue[i].Sent)
this.messageQueue.RemoveAt(i);
}
}

}catch
{
}
}

protected virtual void Listenning()
{

try
{

while(true)
{
System.Threading.Thread.Sleep(200);

foreach(Connection connection in this._connections)
{

if(connection.NetworkStream.CanRead && connection.NetworkStream.DataAvailable)
{

try
{
Message message = Message.Parse(connection);
this.OnMessageReceived(this,new MessageEventArgs(message,connection));
}

catch(Exception ex)
{
connection.NetworkStream.Close();
this.OnConnectionClose(this,new ConnectionEventArgs(connection,ex));
}
}
}
}
}

catch
{
}
}


protected void StartListenAndSend()
{
_listenningthread = new System.Threading.Thread(new System.Threading.ThreadStart(Listenning));
_listenningthread.Start();
_sendthread = new System.Threading.Thread(new System.Threading.ThreadStart(Sendding));
_sendthread.Start();
}

public void EndListenAndSend()
{
_listenningthread.Abort();
_sendthread.Abort();
}



public event MessageEventHandler MessageReceived;
public event MessageEventHandler MessageSent;
public event ConnectionHandler ConnectionClose;
public event ConnectionHandler Connected;


public void OnMessageReceived(object sender,MessageEventArgs e)
{
if(MessageReceived != null)
this.MessageReceived(sender,e);
}

public void OnMessageSent(object sender,MessageEventArgs e)
{
if(MessageSent != null)
this.MessageSent(sender,e);
}

public void OnConnectionClose(object sender,ConnectionEventArgs e)
{
if(ConnectionClose != null)
this.ConnectionClose(sender,e);
}

public void OnConnected(object sender,ConnectionEventArgs e)
{
if(Connected != null)
this.Connected(sender,e);
}
}
}
(8)、SocketFactory.cs文件中的代码:

SocketFactory.cs文件代码
using System;
using System.Net;
using System.Net.Sockets;


namespace SocketLibrary
{

/**//// <summary>
/// 网络通信组件
/// </summary>

public class SocketFactory
{
public static System.Text.Encoding DefaultEncoding = System.Text.Encoding.GetEncoding("GB2312");
}
}
4、将文件和代码建立和粘贴完成后,运行此类库,会在程序所在路径文件夹里的“bin\Debug\”下找到“SocketLibrary.dll”文件,下面开发的Windows服务就需要引用这个dll文件。
第二步再来开发出Windows服务。
1、打开Visual Studio.Net2003,单击菜单中的“文件”——>“新建”——>“项目”,在弹出的对话框左侧选择“Visual C#项目”,在右侧选择“Windows服务”,下方的名称中输入“SocketService”,位置自己随便选择一个路径。
2、删除自动创建的服务文件,新建如下的Windows服务文件“SocketService.cs”。
3、在SocketService.cs文件的设计界面,选择开发环境右侧的“属性”页卡,会在页卡底部发现“添加安装程序(I)”,单击此处后会在解决方案的SocketService工程下多一个服务文件“ProjectInstaller.cs”。
4、在ProjectInstaller.cs文件的设计界面,会看见两个组件“serviceProcessInstaller1”和“serviceInstaller1”。将serviceProcessInstaller1组件的Account属性设置为“LocalSystem”(表示本地系统服务,NetworkService表示网络服务,LocalService表示本地服务,User表示用户服务);再将serviceInstaller1组件的StartType属性设置为“Automatic”(表示服务自动启动,Manual表示手动启动,Disabled表示禁用)。
5、右击解决方案中的“引用”,选择添加引用,在弹出的对话框中选择“浏览”,将前面的“SocketLibrary.dll”添加到此引用。
6、在系统C盘下建立两个文件“SocketService.ini”和“SocketService.log”。SocketService.ini文件是配置SocketService监听的端口号,打开该ini文件在其中编辑下面的内容“端口号:8088”(双引号请不要输入在ini文件的内容里),而SocketService.log是为了记录有关信息的日志。
7、删除SocketService.cs文件的所有代码,将下面的代码拷贝到该文件中:

SocketService.cs文件代码
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.IO;
using SocketLibrary;

namespace SocketService


{
public class SocketService : System.ServiceProcess.ServiceBase

{

/**//// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;
public SocketService()

{
// 该调用是 Windows.Forms 组件设计器所必需的。
InitializeComponent();

// TODO: 在 InitComponent 调用后添加任何初始化
}


组件设计器生成的代码#region 组件设计器生成的代码

/**//// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器
/// 修改此方法的内容。
/// </summary>
private void InitializeComponent()

{
//
// SocketService
//
this.ServiceName = "SocketService";

}
#endregion


/**//// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )

{
if( disposing )

{
if (components != null)

{
components.Dispose();
}
}
base.Dispose( disposing );
}


/**//// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()

{
System.ServiceProcess.ServiceBase.Run(new SocketService());
}

SocketLibrary.Server _server = new SocketLibrary.Server();


/**//// <summary>
/// 设置具体的操作,以便服务可以执行它的工作。
/// </summary>
protected override void OnStart(string[] args)

{
// TODO: 在此处添加代码以启动服务。
try

{
StreamReader ConfigReader = new StreamReader("C:\\SocketService.ini",System.Text.Encoding.GetEncoding("GB2312"));
string str = ConfigReader.ReadToEnd();
string[] Str = str.Split(':');
if (Str.Length == 2)

{
if(Str[0] == "端口号")

{
_server.StartServer(Convert.ToInt32(Str[1]));
StreamWriter LogWriter = new StreamWriter("C:\\SocketService.log",true,System.Text.Encoding.GetEncoding("GB2312"));
LogWriter.Write(DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToShortTimeString() + " SocketService服务已启动\n");
LogWriter.Close();
_server.MessageReceived += new SocketLibrary.SocketBase.MessageEventHandler(_server_MessageReceived);
_server.Connected += new SocketLibrary.SocketBase.ConnectionHandler(_server_Connected);
}
else

{
StreamWriter LogWriter = new StreamWriter("C:\\SocketService.log",true,System.Text.Encoding.GetEncoding("GB2312"));
LogWriter.Write(DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToShortTimeString() + " SocketService.ini文件中无端口号属性,格式应为\"端口号:[输入的端口号]\"\n");
LogWriter.Close();
OnStop();
}
}
else

{
StreamWriter LogWriter = new StreamWriter("C:\\SocketService.log",true,System.Text.Encoding.GetEncoding("GB2312"));
LogWriter.Write(DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToShortTimeString() + " SocketService.ini文件中属性过多,格式应为\"端口号:[输入的端口号]\"\n");
LogWriter.Close();
OnStop();
}
}
catch (Exception e)

{
StreamWriter LogWriter = new StreamWriter("C:\\SocketService.log",true,System.Text.Encoding.GetEncoding("GB2312"));
LogWriter.Write(DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToShortTimeString() + " SocketService服务启动时有错误,错误信息:" + e.Message + "\n");
LogWriter.Close();
OnStop();
}

}

/**//// <summary>
/// 停止此服务。
/// </summary>
protected override void OnStop()

{
// TODO: 在此处添加代码以执行停止服务所需的关闭操作。
_server.StopServer();
StreamWriter LogWriter = new StreamWriter("C:\\SocketService.log",true,System.Text.Encoding.GetEncoding("GB2312"));
LogWriter.Write(DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToShortTimeString() + " SocketService服务已停止\n");
LogWriter.Close();
}

private void _server_MessageReceived(object sender, SocketLibrary.SocketBase.MessageEventArgs e)

{
StreamWriter LogWriter = new StreamWriter("C:\\SocketService.log",true,System.Text.Encoding.GetEncoding("GB2312"));
LogWriter.Write(DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToShortTimeString() + " " + e.Message.MessageBody + "\n");
LogWriter.Close();
}
private void _server_Connected(object sender, SocketLibrary.SocketBase.ConnectionEventArgs e)

{
StreamWriter LogWriter = new StreamWriter("C:\\SocketService.log",true,System.Text.Encoding.GetEncoding("GB2312"));
LogWriter.Write(DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToShortTimeString() + " " + e.Exception.Message + "\n");
LogWriter.Close();
}
}
}
8、在Visual Studio.Net2003的菜单上选择“生成”——>“重新生成解决方案”,当生成成功后,会在程序所在路径文件夹里的“bin\Debug\”下找到“SocketService.exe”文件,记住这个路径和文件名,下一步需要用到。
9、打开“Visual Studio .NET 2003 命令提示”(应该都知道如何打开吧,不知道的可以在评论中询问)。在其中输入“installutil [第8步中的路径和文件名]”(例如:installutil C:\SocketService\bin\Debug\SocketService.exe),按下回车,将会在本机上安装刚开发好的Windows服务,如果要卸载安装过的Windows服务请在“Visual Studio .NET 2003 命令提示”中输入“installutil /u [第8步中的路径和文件名]”(例如:installutil /u C:\SocketService\bin\Debug\SocketService.exe)。
10、制作Windows服务的安装部署工程(略)。
第三步最后开发出一个Socket通信的客户端来验证此服务。
1、和以往建立C/S程序的过程一样,只是将工程名称改为“SocketClientTest”。
2、删除自动创建的Form1,新建窗体“CFrom”。
3、窗体控件与布局见下图:

4、在引用中添加“SocketLibrary.dll”引用(添加方法和SocketService工程添加方法相同)
5、后台代码如下:

CForm.cs文件代码
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace SocketClientTest


{

/**//// <summary>
/// Form1 的摘要说明。
/// </summary>
public class CForm : System.Windows.Forms.Form

{

/**//// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;

public CForm()

{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();

//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}


/**//// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )

{
if( disposing )

{
if (components != null)

{
components.Dispose();
}
}
base.Dispose( disposing );
}


Windows 窗体设计器生成的代码#region Windows 窗体设计器生成的代码

/**//// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()

{
this.button1 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.button2 = new System.Windows.Forms.Button();
this.button3 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(40, 24);
this.button1.Name = "button1";
this.button1.TabIndex = 0;
this.button1.Text = "连接";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(24, 80);
this.textBox1.Name = "textBox1";
this.textBox1.TabIndex = 1;
this.textBox1.Text = "textBox1";
//
// button2
//
this.button2.Location = new System.Drawing.Point(144, 80);
this.button2.Name = "button2";
this.button2.TabIndex = 2;
this.button2.Text = "发送";
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// button3
//
this.button3.Location = new System.Drawing.Point(144, 24);
this.button3.Name = "button3";
this.button3.TabIndex = 3;
this.button3.Text = "停止";
this.button3.Click += new System.EventHandler(this.button3_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(292, 126);
this.Controls.Add(this.button3);
this.Controls.Add(this.button2);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.button1);
this.Name = "CForm";
this.Text = "CForm";
this.Load += new System.EventHandler(this.CForm_Load);
this.ResumeLayout(false);

}
#endregion


/**//// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()

{
Application.Run(new CForm());
}

private System.Windows.Forms.Button button1;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button3;
SocketLibrary.Client client;
private void CForm_Load(object sender, System.EventArgs e)

{
client = new SocketLibrary.Client();
SocketLibrary.SocketFactory factory = new SocketLibrary.SocketFactory();
}


private void button1_Click(object sender, System.EventArgs e)
{
client.StartClient(System.Net.IPAddress.Parse("192.168.5.9"),8088);//此处输入自己的计算机IP地址,端口需和SocketService.ini中的端口号一样
}


private void button2_Click(object sender, System.EventArgs e)
{
SocketLibrary.Message message = new SocketLibrary.Message(SocketLibrary.Message.CommandHeader.SendMessage,1,1,textBox1.Text);
client.messageQueue.Add(message);
}


private void button3_Click(object sender, System.EventArgs e)
{
client.StopClient();
}
}
}
6、运行程序,点击CForm中的“连接”按钮,再在TextBox1中输入部分信息,单击“发送”按钮,看看在C:\SocketService.log中是否记录了CForm窗口中TextBox1中的内容。
到此我们就已经将这个Socket通信Server端的Winodows服务开发完成了。下面提供源程序的下载:
本地下载 SocketLibrary类库源码
本地下载 Server端Socket通信Windows服务源码
本地下载 SocketClientTest源码
本地下载 SocketServerTest源码(没有改变为Windows服务时的程序,即下载时的原程序)
以上程序已在Visual Studio.Net2003下运行通过。
备注:下面有本人的两个评论来修正本随笔中的代码存在的一些问题,请仔细浏览,谢谢浏览本随笔……
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)