随着倒计时的响声,自觉无心工作,只想为祖国庆生。

最近有遇到过这样一个问题,将摄像头识别的行人,车辆实时显示在客户端中。有提供接口,会以Json的数据的形式将实时将识别的对象进行Post提交。所以我们这边先写一个web服务来持续接收数据,再将数据进行解析存入数据库。到这里为止,数据没有问题,都全部存入数据库中,这样还剩下一个实时刷新识别图片的问题。之前的处理方法是每隔5秒左右去读取数据库最新消息,用Timer计时器来解决,这样的话确实能解决问题,但是感觉不是最好的方法,因为摄像头识别的对象有时效性,比如半夜几乎没人通过,这个时候后台还在去捞取最新数据进行判断就比较消耗资源。所以我先想到的是用 TCP方法来处理, web在解析图片的时候, 进行发送,winform客户端进行接收。貌似可以解决问题,先上代码

        private void button1_Click(object sender, EventArgs e)
{
//创建TCP客户端对象
TcpClient tcpClient = new TcpClient();
//添加目标(服务器)主机的IP、端口号
tcpClient.Connect(IPAddress.Parse("172.16.0.217"), );
//网络流 数据的形式
NetworkStream networkStream = tcpClient.GetStream();
if (networkStream.CanWrite)
{
//待发送数据转Byte[]
Byte[] bytSend = Encoding.UTF8.GetBytes(textBox1.Text);
networkStream.Write(bytSend, , bytSend.Length);
}
else
{
MessageBox.Show("无法写入数据流"); networkStream.Close();
tcpClient.Close(); return;
}
//流创建完需要及时关闭
networkStream.Close();
tcpClient.Close(); }

这里是TCP的客户端,指定了接收端的IP和端口号,以及发送的数据流,同样在服务端选择接受这些流数据。服务端要持续接收数据,就必须开启一个线程进行监听

        private void Form1_Load(object sender, EventArgs e)
{
//初始化加载数据
Thread thread = new Thread(new ThreadStart(Listen));
thread.Start();
} //线程内向文本框txtRecvMssg中添加字符串及委托
private delegate void serverRecDeg(string s);
private void ReceiveMsg(string mes)
{
textBox1.Text = "Time:" + DateTime.Now.ToLongTimeString() + "Data:" + mes;
} //监听数据
private void Listen()
{
//socket 对象
Socket sock = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
sock.Bind(new IPEndPoint(IPAddress.Any, 8056)); //不断监听端口
while (true)
{
sock.Listen();
Socket socket = sock.Accept();
NetworkStream ntwStream = new NetworkStream(socket);
StreamReader strmReader = new StreamReader(ntwStream);
//winform UI控件赋值,如果有线程,则需要用Invoke 来赋值,则否报错
Invoke(new serverRecDeg(ReceiveMsg),new object[] { strmReader.ReadToEnd() });
socket.Close();
}
}

以上是TCP客户端发送数据,服务端持续接收。刚开始自认没问题,但是后来一想确实不可行。我web服务端是发送数据的,客户端是用来接收数据。TCP是客户端指定服务端唯一的IP 和端口号进行数据的传输,这里明显就冲突了,如果在Web服务端用TCP发送数据,

就只能有一个客户端进行接收,需求是winform最后要部署到不同机器上,这种思路肯定不行。思来想去,最后在同事的指点下,想到了广播这一思路。在web服务端每次解析到图片的时候,发一个广播,然后隐藏在局域网内的各个客户端就可以进行收听,解析后将图片

        //定义对象
private static Socket sock;
private static IPEndPoint ipendPoint;
private static byte[] data; //发送广播
public static void UdpSend(byte[] bytes1)
{
//sock 对象,指定UDP协议
sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
ipendPoint = new IPEndPoint(IPAddress.Broadcast, );
//赋值
data = bytes1;
sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, );
//发送
sock.SendTo(data, ipendPoint); }

这里使用的是UDP广播,代码量很少,发送端已经完成,剩下的就是客户端持续接收广播

        public void Receive()
{
try
{
//Scok 对象,设置UDP协议
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
//超时时间
sock.ReceiveTimeout = ;
//广播的端口号指定
IPEndPoint iep = new IPEndPoint(IPAddress.Any, );
sock.Bind(iep);
EndPoint ep = (EndPoint)iep;
//数据接收(指定异步接收的方法)
sock.BeginReceive(buffer, , buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), sock); }
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
} //指定单次接收图片流缓冲区的大小
static byte[] buffer = new byte[]; //异步接收
public void ReceiveMessage(IAsyncResult ar)
{
try
{
var socket = ar.AsyncState as Socket;
var length = socket.EndReceive(ar);
//读取出来消息内容
//var message = Encoding.UTF8.GetString(buffer, 0, length);
//前三个长度为对象类型 车辆/行人 ,后面识别图片
//解析图片类型
string objType = System.Text.Encoding.Default.GetString(buffer.Skip().Take().ToArray());
//解析图片
Image img = convertImg(buffer.Skip().ToArray());
//显示消息
this.Invoke(new Action(() => { SetPicBoxImg(objType, img); }));
//接收下一个消息(递归)
socket.BeginReceive(buffer, , buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

这些做完,剩下的就是将接收广播的方法写入到后台线程中,在窗体运行的时候启动即可

 Thread td = new Thread(new ThreadStart(Receive));
td.IsBackground = true;
td.Start();

好了,事情到这里基本就结束了,可以看出来,代码量很少,却能解决实时刷新的需求。以后遇到事情一定要思路明确,不然一开始钻进TCP的死胡同里,怎么都出不来,白白浪费时间不说,把人也搞得很疲惫。这里多谢同事的指点,以后多像技术高手学习,毕竟阅历有时候真的就是硬实力。

UDP广播 与 TCP客户端 --服务端的更多相关文章

  1. 利用TCP 客户端---->服务端 传送文件到指定路径,并返回一个友好的回馈

    首先盲写的一个传输文件的方法,但测试发现了一个非常不容易发现的问题,这里先说明一下. 错误的代码如下: package com.TCP.java; import java.io.File; impor ...

  2. TCP客户端 服务端详细代码

    本文章转自http://www.myexception.cn/program/1912019.html TCP网络编程中connect().listen()和accept()三者之间的关系 基于 TC ...

  3. TCP/IP网络编程之基于TCP的服务端/客户端(一)

    理解TCP和UDP 根据数据传输方式的不同,基于网络协议的套接字一般分为TCP套接字和UDP套接字.因为TCP套接字是面向连接的,因此又称为基于流(stream)的套接字.TCP是Transmissi ...

  4. TCP/IP网络编程之基于TCP的服务端/客户端(二)

    回声客户端问题 上一章TCP/IP网络编程之基于TCP的服务端/客户端(一)中,我们解释了回声客户端所存在的问题,那么单单是客户端的问题,服务端没有任何问题?是的,服务端没有问题,现在先让我们回顾下服 ...

  5. [并发并行]_[线程模型]_[Pthread线程使用模型之三 客户端/服务端模型(Client/Server]

    Pthread线程使用模型之三 客户端/服务端模型(Client/Server) 场景 1.在客户端/服务端模型时,客户端向服务端请求一些数据集的操作. 服务端执行执行操作独立的(多进程或跨网络)– ...

  6. win10操作系统下oracle11g客户端/服务端的下载安装配置卸载总结

    win10操作系统下oracle11g客户端/服务端的下载安装配置卸载总结 一:前提 注意:现在有两种安装的方式 1. oracle11g服务端(64位)+oracle客户端(32位)+plsql(3 ...

  7. 基于TCP的socket套接字的网络编程(客户端/服务端模式)

    于数据完整性要求较高的场合,就应采用TCP协议. IP网络层提供IP寻址和路由.因为在网络上数据可以经由多条线路到达目的地,网络层负责找出最佳的传输线路. IP地址与数据包: IP层就是把数据分组从一 ...

  8. TCP通信服务端及客户端代码

    Java TCP通信使用的是Socket(客服端)和ServerSocket(服务端),具体代码如下. server端代码: import java.io.BufferedReader; import ...

  9. tcp文件下载客户端+服务端

    客户端: import socket if __name__ == '__main__': # 创建tcp客户端socket tcp_client_socket = socket.socket(soc ...

随机推荐

  1. Physics Experiment 弹性碰撞 [POJ3684]

    题意 有一个竖直的管子内有n个小球,小球的半径为r,最下面的小球距离地面h高度,让小球每隔一秒自由下落一个,小球与地面,小球与小球之间可视为弹性碰撞,让求T时间后这些小球的分布 Input The f ...

  2. NumPy数组对象

    1.创建NumPy数组 import numpy as np # 创建3*2*4的三维数组 a = np.arange(24).reshape(3, 2, 4) # 打印三维数组的所有元素 print ...

  3. [LeetCode] Encode N-ary Tree to Binary Tree 将N叉树编码为二叉树

    Design an algorithm to encode an N-ary tree into a binary tree and decode the binary tree to get the ...

  4. 超小Web手势库AlloyFinger原理(转载)

    目前AlloyFinger作为腾讯手机QQ web手势解决方案,在各大项目中都发挥着作用. 感兴趣的同学可以去Github看看: https://github.com/AlloyTeam/AlloyF ...

  5. Spring Boot @EnableWebMvc 与 mvc 配置

    注意: 1.小心使用  @EnableWebMvc 注解 根据官方文档,尽量不要使用 @EnableWebMvc 注解,因为它会关闭默认配置. ① 你希望关闭默认配置,自己完全重新实现一个 @Enab ...

  6. jenkins-参数化构建(二)插件:Extended Choice Parameter

    一.Extended Choice Parameter插件 这个插件相对丰富,安装过程就不过多介绍了,在点击项目设置后会出现下载的插件名字. 写在文件中构建时效果如下:

  7. Python读取xlsx翻译文案

    首先安装Python,然后安装模块 //查找模块(非必须) pip search xlrd //安装模块 pip install xlrd 由于输出要是utf-8所以需要设置默认环境为utf-8 # ...

  8. 严重:one or more listeners failed. Full details will be found in the appropriate container log file

    one or more listeners failed. Full details will be found in the appropriate container log file   这句话 ...

  9. Node.js、npm、vue-cli 的安装配置环境变量

    我安装node.js是为了学习vue,需要用到npm,所以就把node.js安装了,安装node.js会带有npm的安装. 在安装node.js之前,我们需要了解以下三个内容. npm: Nodejs ...

  10. linux 对MTD分区nand flash的烧写和读取

    使用mtd-utils工具实现对flash的升级分区的烧写yaffs2 yaffs2的格式是根据所使用的nandflash来制作的,不同的nandflash,得到的yaffs2是不一样的,具体可以参考 ...