---------------------- ASP.Net+Android+IO开发、.Net培训、期待与您交流! ----------------------
● Socket的相关概念
1) Socket(套接字):用于描述IP地址和端口,是一个通信链的句柄(其实就是两个程序通信用的);
2) http协议使用80端口,ftp协议使用21端口,smtp协议使用23端口;
3) Socket通信的两种方式:
(1)流式Socket(stream):
是一种面向连接的Socket,针对于面向连接的TCP服务应用,安全,但是效率低;
(2)数据报式Socket(datagram):
是一种无连接的Socket,对应于无连接的UDP服务应用,不安全(丢失,顺序混乱,在接收端要分析重排及要求重发),但效率高;
● Socket一般应用模式(服务端和客户端的通信)
1) 服务端和客户端的Socket
(1)服务端的Socket(至少2个):
一个负责监听客户端连接请求的watch socket(绑定到一个指定的IP和端口上)
每成功监听到一个客户端的连接请求,watch socket就在服务端产生一个对应的负责和客户端通信的connection socket(端口大于1024)
(2)客户端的Socket:
一个负责和服务端通信的client socket(指定要连接的服务端的IP和端口);
2) 其它:
(1)socketClient.RemoteEndPoint.Tostring()或者
socketConnection.RemoteEndPoint.Tostring():获得通信套接字的远程IP和端口号
(2)Buffer.BlockCopy(Arraysrc,int srcOffset,Array dst,int dstOffset,int count):将指定数目的字节从起始于特定偏移量的源数组复制到起始于特定偏移量的目标数组(src:源数组,srcOffset:从源数组的什么位置开始复制,dst:目标数组,dstOffset:从目标数组的什么位置开始存入,count:源数组中要复制的字节数)
3) Socket建立连接:
(1)服务端:
//创建一个负责监听客户端连接请求的watch socket,并指定其寻址方案、套接字类型、协议类型
Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipAddress = IPAddress.Parse("IP地址");
//设置IP和端口号
IPEndPoint endPoint = new IPEndPoint(ipAddress,端口号);
//绑定到指定的IP地址和端口号上
socketWatch.Bind(endPoint);
//设置监听队列的长度
socketWatch.Listen(10);
//Accept():开始监听,返回一个负责和客户端通信的connection socket;会阻断线程,可以创建一个负责监听的线程来处理;
监听多个客户端的连接请求,可以用循环:while(true);从而产生多个负责和客户端通信的connection socket,可以用字典(键值对的集合)Dictionary<string,Thread>来存放对应的< IP和端口号,socketConnection 套接字> ------>对应的多个socketConnection. Receive()的线程也可以用字典来存放;
Socket socketConnection = socketWatch.Accept();
(2)客户端
//创建一个负责和服务端通信的client socket,并指定其寻址方案、套接字类型、协议类型
Socket socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipAddress = IPAddress.Parse("IP地址");
//设置IP和端口号
IPEndPoint endPoint = new IPEndPoint(ipAddress,端口号);
//Connect():建立和服务端的连接
socketClient.Connect(endPoint);
1) Socket数据通信:
(1)发送数据消息:
//将指定的字符串中的所有字节编码为一个字节序列
byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(string str);
//Send():发送数据消息
socketClient.Send(arrMsg); 或者 socketConnection.Send(arrMsg);
(2)接收数据消息:
//定义一个接收数据消息的缓存区(2M的字节数组)
byte[] arrMsgRec = new byte[1024 * 1024 * 2];
//Receive():接收数据消息,并将数据消息存入缓存区,返回字节的长度;会阻断线程,可以创建一个负责接收数据消息的线程来处理;
接收多条数据消息,可以用循环:while(true);
socketClient.Receive(arrMsgRec); 或者 socketConnection.Receive(arrMsgRec);
//GetString():将指定字节数组中的一个字节序列解码为一个字符串(index:第一个要解码的字节索引,count:要解码的字节数)
string strMsgRec = System.Text.Encoding.UTF8.GetString(arrMsgRec,int index,int count);
(3)发送文件数据:
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog()==DialogResult.OK)
{
//创建一个字节流对象(指定的路径字符串的文件名,指定打开文件的方式)
using (FileStream fileStream = new FileStream(ofd.FileName,FileMode.Open))
{
//定义一个接收文件数据的缓存区(2M的字节数组)
byte[] arrFileRec = new byte[1024 * 1024 * 2];
//Read():从流中读取指定数目的字节块并存入到指定的缓存区中,返回从流中读取的字节数(offset:从缓存区的什么位置开始存入,count:从流中读取的字节数)
fileStream.Read(arrFileRec,int offset,int count);
//Send():发送文件数据
socketClient.Send(arrFileRec);
}
}
(4)接收文件数据:
SaveFileDialog sfd = new SaveFileDialog();
if (sfd.ShowDialog() == DialogResult.OK)
{
using (FileStream fileStream = new FileStream(sfd.FileName,FileMode.Create))
{
//Write():从起始于特定偏移量的缓存区中读取指定数目的字节并写入到流中(array:缓存区,offset:从缓存区的什么位置开始读取,count:从缓存区中读取的字节数)
fileStream.Write(byte[] array,int offset,int count);
}
}
---------------------- ASP.Net+Android+IO开发、.Net培训、期待与您交流! ----------------------