最近准备做一个考试系统,所以学习了一下C/S的通信,就现在所知的来说,一般用的通信方式有Web Service、Remoting,还有一种较新的技术WCF,
但我还没学习到,所以暂不涉及。
开篇即将记录的是最基本的Socket,在.Net中,微软将Socket进行了很好的封装,在基本的通信中,需要在客户端和服务器端各有一个Socket,使使用者不
用了解底层的如TCP、Http或Udp协议就可以很轻松的使用。
下面是一个简单的TcpClient和TcpListener的应用。
服务器端通过异步的操作在后台监听所有对5200端口的访问,并获取IP和访问的信息。因为从TcpClient获得的数据流是NetWorkStream,所以我们需要相
应的流对象来对其进行解析并转换为String,但由于在先前设置的缓存大小为256字节,所以当我们获得的数据小于256时,后面将会是自动填充的一连串"\0",所以在
获取数据后还应该将后面的"\0"替换掉,或是根据NetWorkStream的Read方法返回的长度,只截取我们需要的字节数,
可能有人会问,当传输的数据大于256时呢? 这时我们需要的是分步来读取,每次读取我们能缓存的大小,并写到另外的流中保存,直到NetWorkStream的
Read方法返回的值等于0。
好了,本篇暂时到这里为止。
下面是服务器端的代码:
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Threading;
using
System.Net.Sockets;
namespace
AsyncWaitingConnect
{
delegate
void
asycnDelegate();
class
Program
{
//
声明委托
static
asycnDelegate del;
static
TcpListener listener;
static
byte
[] infoBytes
=
new
byte
[
256
]; //设定缓存为256
static
void
Main(
string
[] args)
{
//
完成时的回调委托,并绑定StopListen方法
AsyncCallback callBack
=
new
AsyncCallback(StopListen);
listener
=
new
TcpListener(
5200
);
listener.Start();
//
实例化委托
del
=
new
asycnDelegate(beginWait);
//
异步开始监听连接到本机的Client
del.BeginInvoke(callBack,
0
);
//
任意输入停止监听
Console.WriteLine(
"
Wait for Client
.\nEnter to Stop waiting
"
);
Console.ReadLine();
listener.Stop();
Console.ReadLine();
}
static
void
beginWait()
{
TcpClient client;
string
clientIP, clientInfo;
//
开始监听
while
(
true
)
{
try
{
//
截断方法,用以等待客户端连接
client
=
listener.AcceptTcpClient();
//
获取客户端的IP
clientIP
=
client.Client.RemoteEndPoint.ToString();
//
获取来自客户端信息的字节流
NetworkStream ns
=
client.GetStream();
//
转换并输出客户信息
int
no
=
ns.Read(infoBytes,
0
,
256
);
clientInfo
=
UnicodeEncoding.Unicode.GetString(infoBytes,0,no);
//
输出已连接客户的信息
Console.WriteLine(
"
Connected IP is {0}, name is{1}
"
,
clientIP,clientInfo
);
}
catch
(Exception e)
{
Console.WriteLine(
"
连接停止!
"
);
return
;
}
}
}
//
回调的方法
static
void
StopListen(IAsyncResult ar)
{
del.EndInvoke(ar);
}
}
}
在客户端中,连接至服务器端,同时发送客户端信息。
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Net.Sockets;
namespace
AsycnWaitingConnectsClient
{
class
Program
{
static
void
Main(
string
[] args)
{
TcpClient client;
System.Net.IPAddress ip
=
System.Net.IPAddress.Parse(
"
127.0.0.1
"
);
for
(
int
i
=
0
; i
<
5
; i
++
)
{
client
=
new
TcpClient();
try
{
client.Connect(ip,
5200
);
}
catch
(Exception e)
{
Console.WriteLine(e.Message);
}
byte
[] Info
=
UnicodeEncoding.Unicode.GetBytes(
"
MyName is
"
+
i.ToString());
client.Client.Send(Info);
}
Console.ReadLine();
}
}
}
PS:在这里使用异步操作的原因是考虑到之后将
实现的WinForm的监听,如果使用同步监
听,那在监听的同时将会使整个窗体失去响
应...这是后面将会谈到的,这里略过。