您的位置:首页 > 其它

丛林战争项目七之在服务器端解析数据

2017-11-07 18:39 204 查看
1.TCP WebServer-->右键“添加”-->新建项-->类 -->填写类名“Message”,其中Message的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TCP_WebServer
{
class Message
{
private byte[] data = new byte[1024];                       //定义一个数组用来存取数据,数组的长度要保证可以存下所有的消息
private int startIndex = 0;                                 //表示存取了多少个字节的数据在数组里面

public void AddCount(int count)                             //提供一个增加数量的方法
{
startIndex += count;
}

public byte[]Data                                           //提供一个返回data数组的方法
{
get { return data; }
}

public int StartIndex
{
get { return startIndex; }
}

public int RemainSize
{
get { return data.Length - startIndex; }                 //剩余的空间
}

public void ReadMessage()                                    //解析数据
{
while (true)
{
if(startIndex <= 4)
return;
int count = BitConverter.ToInt32(data,0);               //获取数据的长度,从索引为0的位置开始读取4个字节
if(startIndex -4 >= count)                              //前四个字节是数据的长度,如果减去长度大于数据字节长度,则表示数据可以被完整地保存
{
string s = Encoding.UTF8.GetString(data,4,count);
Console.WriteLine("解析出来一条数据:"+s);
Array.Copy(data, count + 4, data, 0, startIndex - 4);
startIndex -= (count + 4);
}
else                                                     //数据不完整
{
break;
}
}

}
}
}


2.客户端的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;

namespace TCP_Client
{
class Program
{
static void Main(string[] args)
{
StartClientAnsync();

}

static void StartClientAnsync()
{
//创建socket
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipAddress = IPAddress.Parse("192.168.1.6");                //创建ip
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 180);              //绑定端口号
clientSocket.Connect(ipEndPoint);                                    //与远程主机建立连接

//向客户端发送一条消息
byte[] data = new byte[1024];
int count = clientSocket.Receive(data);                             //接收数据
String msg = Encoding.UTF8.GetString(data, 0, count);
Console.Write(msg);

for (int i=0;i<100;i++)
{
clientSocket.Send(Message.GetBytes(i.ToString()));
}

Console.ReadKey();
clientSocket.Close();                                               //
}
}
}


3.服务端的代码

在接收数据时:



在接收到数据的回调中,执行下面的方法



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;

namespace TCP_WebServer
{
class Program
{
static void Main(string[] args)
{
startServerSync();                                      //调用服务端
Console.ReadKey();                                      //调用完后让程序暂停一下
}
static void startServerSync()
{
//服务端的开发
//创建一个Socket
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//192.168.1.7这个是本机的ipv4地址,这个地址是会变动的,路由器运行时间久了就会变化
//127.0.0.1是一个万用地址,如果是在本机上使用则是本机的地址,如果换一台机器,则是另一台机器的地址
//IPAddress:xxx.xx.xx.xx   IpEndPoint:xxx.xx.xx.xx:prot
//IPAddress iPAddress = new IPAddress(new byte[] { 192,168,1,7});       //这种方式通过传递一个数组将地址解析出来,但是这种方式不推荐
IPAddress ipAddress = IPAddress.Parse("192.168.1.6");                   //创建ip
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 180);                 //绑定端口号
serverSocket.Bind(ipEndPoint);                                          //绑定ip和端口号
serverSocket.Listen(10);                                                //参数backLog为队列中最多可以处理监听多少个
//Socket clientSocket = serverSocket.Accept();                          //接收一个客户端连接
serverSocket.BeginAccept(AcceptCallBack,serverSocket);                  //该方法调用后会等待客户端的连接,将serverSocket作为一个参数进行传递

}

static Message msg = new Message();

//接收到客户端的连接
static void AcceptCallBack(IAsyncResult ar)
{
Socket serverSocket = ar.AsyncState as Socket;
Socket clientSocket = serverSocket.EndAccept(ar);                   //完成接收

//向客户端发送一条消息
String msgStr = "Hello client!你好......";                             //需要传递的内容
byte[] data = System.Text.Encoding.UTF8.GetBytes(msgStr);              //因为含有中文,所以需要使用一个可以将中文解析成byte数组的方法
clientSocket.Send(data);                                            //发送消息
//第一个参数是所要读取的数组,第二个参数是开始的位置,第三个参数是剩余的字节
clientSocket.BeginReceive(msg.Data, msg.StartIndex, msg.RemainSize, SocketFlags.None, ReceiveCallBack, clientSocket);
serverSocket.BeginAccept(AcceptCallBack,serverSocket);              //继续等待下一个接收

}

static byte[] dataBuffer = new byte[1024];
//收到客户端的消息
static void ReceiveCallBack(IAsyncResult ar)
{
Socket clientSocket = null;
try
{
clientSocket = ar.AsyncState as Socket;                          //通过IAsyncResult获取到clientSocket
int count = clientSocket.EndReceive(ar);                         //结束接收
if(count == 0)
{
clientSocket.Close();                                        //如果接收到的数据长度是0,则关闭客户端
return;
}
msg.AddCount(count);                                                //添加数据
clientSocket.BeginReceive(msg.Data, msg.StartIndex, msg.RemainSize, SocketFlags.None, ReceiveCallBack, clientSocket);
msg.ReadMessage();

//String msgStr = Encoding.UTF8.GetString(dataBuffer, 0, count);      //获取接收到的数据
//Console.WriteLine("从客户端接收到数据:" + msgStr);                 //输出获取到的数据
//上面的代码只会完成一条上面消息的接收,要想重复调用,需要重新调用一下下面的方法,至此就完成了一个循环
//clientSocket.BeginReceive(dataBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);
}
catch(Exception e)
{
Console.WriteLine(e);
if (clientSocket != null)
{
clientSocket.Close();
}
}
finally
{

}
}

}
}

运行后的结果:数据被正常地解析了

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: