Socket网络通讯
添加全局变量
//添加4个与service网络服务相关的变量
private static byte[] result = new byte[1024]; //8位无符数组变量,用来存储接收到的数据
private Socket MyServerSocket; //用来创建一个与本地IP的服务端
private Socket MyClientSocket; //用来当作客户端连接的套接字
private bool ServerFlag = false; //用来判断本地服务器是否打开
在主程序运行的时候添加一个打开服务器的方法
public Main()
{
InitializeComponent();
TcpInit(7788);
}
创建一个打开服务器的方法,将套接字实例化,设置成一个IPV4的地址,双向可靠的字节流,TCP协议类型与本地终端连接,IP为自动获取的一个本地终端788端口打开服务器的端口,设置监听频率为10ms一次,开启异步传入客户端连接。
public void TcpInit(int Port)
{
try
{
MyServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
MyServerSocket.Bind(new IPEndPoint(IPAddress.Any, Port));
MyServerSocket.Listen(10); //监听频率为10ms
MyServerSocket.BeginAccept(new AsyncCallback(ClientAccepted), MyServerSocket);
ServerFlag = true;
}
catch (Exception ex)
{
txtBox_RunRecord.Text = txtBox_RunRecord.Text.Insert(0, DateTime.Now.ToString() + " 出错" + ex + "\r\n");
}
}
添加一个异步传入连接客户端的方法,就是当有客户端连接的时候就会触发本函数。
private void ClientAccepted(IAsyncResult ar)
{
if (ServerFlag == false) 、//判断服务器是否打开
{
return;
}
//通过继承下来的ar创建一个新的套接字socket
Socket socket = ar.AsyncState as Socket;
MyClientSocket = socket.EndAccept(ar);
if (MyClientSocket == null)
{
return;
}
//开始接收来自客户端的信息,存放在result数组中
MyClientSocket.BeginReceive(result, 0, result.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), MyClientSocket);
//循环调用本函数,实现了循环的接收数据
socket.BeginAccept(new AsyncCallback(ClientAccepted), socket);
}
创建一个异步接收数据的方法
private void ReceiveMessage(IAsyncResult ar)
{
try
{
//新建一个套接字变量来继承异步客户端连接的套接字
Socket socket = ar.AsyncState as Socket;
//新建一个32位有符号整数变量赋值为结束的异步读取值
var length = socket.EndReceive(ar); //停止接收数据
//新建一个变量赋值为接收到的数据,并且进行转码为字符串
string message = Encoding.ASCII.GetString(result, 0, length);
TcpServerRecv(message);
//接收下一个消息因为这是一个递归的调用,所以这样就可以一直接收消息了。
socket.BeginReceive(result, 0, result.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);
}
catch
{
}
}
循环接收来自客户端的信息进行比较处理,此函数中的Q1信息是客户端发送来的。
private void TcpServerRecv(string mes)
{
//多线程实现信息的提示
BeginInvoke(new MethodInvoker(delegate
{
txtBox_RunRecord.Text = txtBox_RunRecord.Text.Insert(0, DateTime.Now.ToString() +" 客户端请求信息: "+ mes + "\r\n");
}));
if (mes == "Q1") //如果接收到的信息为Q1
{
try
{
getcoord = "0";
recon();
int ModelNum = -1;
try
{
//判断是大写Q还是小写Q
ModelNum = Convert.ToInt32(mes[1] - 48) - 1;
}
catch
{
BeginInvoke(new MethodInvoker(delegate
{
txtBox_RunRecord.Text = txtBox_RunRecord.Text.Insert(0, DateTime.Now.ToString() + " mes:协议异常" + "\r\n");
}));
SendData("-1,-1,-1\r");
return;
}
if (ModelNum > 3 || ModelNum < 0)
{
BeginInvoke(new MethodInvoker(delegate
{
txtBox_RunRecord.Text = txtBox_RunRecord.Text.Insert(0, DateTime.Now.ToString() + " mes:协议异常" + "\r\n");
}));
SendData("-1,-1,-1\r");
return;
}
if (EffectiveFlag == false) //服务器没有打开提示无模板
{
BeginInvoke(new MethodInvoker(delegate
{
txtBox_RunRecord.Text = txtBox_RunRecord.Text.Insert(0, DateTime.Now.ToString() + " mes:无模板" + "\r\n");
}));
SendData("-1,-1,-1\r");
return;
}
string VisionMes = getcoord;
if (VisionMes == "-1,-1,-1\r")
{
BeginInvoke(new MethodInvoker(delegate
{
txtBox_RunRecord.Text = txtBox_RunRecord.Text.Insert(0, DateTime.Now.ToString() + " mes:模板匹配失败" + "\r\n");
}));
SendData("-1,-1,-1\r");
return;
}
else
{
string mess = "";
mess = Convert.ToString((double)QXX) + "," + Convert.ToString((double)QYY) + "," + Convert.ToString((double)jiaodu) + "\r";
SendData(mess); //将机器人的坐标信息发送给客户端
}
}
catch
{
BeginInvoke(new MethodInvoker(delegate
{
txtBox_RunRecord.Text = txtBox_RunRecord.Text.Insert(0, DateTime.Now.ToString() + " mes:协议异常" + "\r\n");
}));
SendData("-1,-1,-1\r");
}
}
else
{
BeginInvoke(new MethodInvoker(delegate
{
txtBox_RunRecord.Text = txtBox_RunRecord.Text.Insert(0, DateTime.Now.ToString() + " 客户端已断开或未连接" + "\r\n");
}));
SendData("-1,-1,-1\r");
}
}
当服务器向客户端发送数据时的处理函数
private void SendData(string Command_send)
{
try
{
//转成二进制的码发送出去
MyClientSocket.Send(Encoding.ASCII.GetBytes(Command_send));
}
catch
{
}
}