Socket通信是实现TCP/IP的一种有效形式,它属于较底层的网络通信机制,可以很灵活的操纵,来传输信息。Socket使用非常广泛,通用性强,HTTP通信也是基于TCP的一种,像常见的即时聊天工具,QQ、飞信、微信等都基于Socket,多数使用UDP,而Windows远程桌面连接也是TCP+UDP结合。
TCP是一种面向连接(连接导向)的、可靠的、基于字节流的运输层通信协议,多用于对连接质量要求较高的环境下,要求在保持连接的状态下才可以传输数据,提供可靠的信息传送服务,如mstsc(远程桌面连接)。
UDP是OSI参考模型中一种无连接的传输层协议,它主要用于不要求分组顺序到达的传输中,分组传输顺序的检查与排序由应用层完成,提供面向事务的简单不可靠信息传送服务。UDP 协议基本上是IP协议与上层协议的接口。UDP协议适用端口分别运行在同一台设备上的多个应用程序。像QQ这种软件,就会出现消息传送失败的情况。
在Windows Phone 7的时代就支持了Socket通信,相关的类封装在名为System.Net.Sockets的命名空间中,并支持TCP和UDP两种方式。
注意,由于Windows Phone的很多操作变为异步方式,所以Socket相关的方法方式也为异步。对于TCP,首先要调用ConnectAsync方法发出连接请求,其次,连接成功后,要调用ReceiveAsync方法和SendAsync方法收发数据,最后,不需要时要将其关闭,以免下次建立连接是出现错误。
而对于UDP,由于是无连接的,即收发数据前并不需要建立连接,因此可以直接通过ReceiveFromAsync方法和SendToAsync方法收发数据。
实战演练:
首先要在桌面上构建一个Windows程序(可以使用WPF、Windows Form或者控制台),这里以WPF为例,建立一个所谓的服务器。
const int PORT = 8899; //设置要绑定的端口号
const int BUFFER_SIZE = 1024; //设置接收消息缓冲区的最大长度
Socket SK_Server = null, SK_Client = null;
public MainWindow()
{
SK_Server = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp); //初始化Socket实例
IPEndPoint EndIP = new IPEndPoint(IPAddress.Any, PORT);
SK_Server.Bind(EndIP);
SK_Server.Listen(100);
SK_Server.BeginAccept(new AsyncCallback(GetSocketBack), null);
InitializeComponent();
}
void GetSocketBack(IAsyncResult Result)
{
try
{
SK_Client = SK_Server.EndAccept(Result);
SocketAsyncEventArgs Args = new SocketAsyncEventArgs();
Args.SetBuffer(new byte[BUFFER_SIZE], 0, BUFFER_SIZE);
Args.Completed += (s, e) =>
{
if (e.SocketError == SocketError.Success)
{
try
{
string msg = Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred);
Console.WriteLine(msg);
}
catch
{
}
}
};
SK_Client.ReceiveAsync(Args);
}
catch
{
}
SK_Server.BeginAccept(new AsyncCallback(GetSocketBack), null);
}
客户端:
public partial class MainWindow : Window
{
const int PORT = 8899;
const int BUFFER_SIZE = 1024;
static ManualResetEvent Evt = new ManualResetEvent(false);
Socket Client = null;
SocketAsyncEventArgs Args = new SocketAsyncEventArgs();
public MainWindow()
{
InitializeComponent();
this.Loaded += MainWindow_Loaded;
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
DnsEndPoint Dns = new DnsEndPoint("127.0.0.1", PORT);
Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
SocketAsyncEventArgs Args = new SocketAsyncEventArgs();
Args.RemoteEndPoint = Dns;
Evt.Reset();
Args.Completed += (i, s) =>
{
if (s.SocketError == SocketError.Success)
{
Dispatcher.BeginInvoke((Action)delegate()
{
MessageBox.Show("连接成功!");
});
}
};
Client.ConnectAsync(Args);
Evt.WaitOne(100);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Args = new SocketAsyncEventArgs();
byte[] Content = Encoding.UTF8.GetBytes("Hello");
Args.SetBuffer(Content, 0, Content.Length);
Args.Completed += (i, s) =>
{
Evt.Set();
};
Evt.Reset();
Client.SendAsync(Args);
Evt.WaitOne(100);
}
这样就能使用Socket的TCP协议进行通信了,这个代码有些怪怪的,还有UDP待续……