惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Security Affairs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Jina AI
Jina AI
P
Palo Alto Networks Blog
GbyAI
GbyAI
大猫的无限游戏
大猫的无限游戏
A
Arctic Wolf
Hugging Face - Blog
Hugging Face - Blog
小众软件
小众软件
Y
Y Combinator Blog
T
The Blog of Author Tim Ferriss
Blog — PlanetScale
Blog — PlanetScale
S
Schneier on Security
V
Vulnerabilities – Threatpost
C
Cybersecurity and Infrastructure Security Agency CISA
雷峰网
雷峰网
T
Tenable Blog
人人都是产品经理
人人都是产品经理
T
Tor Project blog
C
Cyber Attacks, Cyber Crime and Cyber Security
AWS News Blog
AWS News Blog
Microsoft Security Blog
Microsoft Security Blog
J
Java Code Geeks
Scott Helme
Scott Helme
SecWiki News
SecWiki News
C
CERT Recently Published Vulnerability Notes
Recorded Future
Recorded Future
I
InfoQ
Security Archives - TechRepublic
Security Archives - TechRepublic
Help Net Security
Help Net Security
Cloudbric
Cloudbric
C
Check Point Blog
Engineering at Meta
Engineering at Meta
TaoSecurity Blog
TaoSecurity Blog
B
Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园_首页
N
News and Events Feed by Topic
云风的 BLOG
云风的 BLOG
MyScale Blog
MyScale Blog
腾讯CDC
量子位
Application and Cybersecurity Blog
Application and Cybersecurity Blog
K
Kaspersky official blog
Vercel News
Vercel News
F
Full Disclosure
T
Troy Hunt's Blog
Forbes - Security
Forbes - Security
S
Security @ Cisco Blogs

博客园 - ю意思я

视频播放的进化(一) WPF初体验 C#实现开关显示器功能 图片裁剪 共享文件夹 w32Time服务(NTP)的一些配置 ShutdownAPI 将文件读取到内存中 在windows server 2003服务器上提供NTP时间同步服务 如何与使用DHCP获取IP地址的设备组网 在VS内添加Web Reference 如何消除锯齿,在图片上画出高质量的文字 如何让Firefox3支持迅雷 获取和设置IP地址 判断字符串是否为IPv4地址 axWindowsMediaPlayer操作 关于相对路径匹配的问题 ToFriendlyFileSize Class的设计
图片同步
ю意思я · 2010-05-21 · via 博客园 - ю意思я

  尝试这样一个思路,用UDP组播的方式,由一个发送端在组内发布时间计数,所有接收端以此计数作为相对时间,来定位当前应该显示哪张图片;

  发送端代码如下(此段代码为站在巨人的肩膀上,引用自小白的Blog):

发送端

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;namespace CommandLine {
    
class Program {
        
static void Main(string[] args) {
            IPAddress ip 
= IPAddress.Parse("224.1.2.3");
            Socket s 
= new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 
1);
            IPEndPoint ipep 
= new IPEndPoint(ip, 5000);

            Console.WriteLine(

"Begin Connect...");int interval = 20;
            
int sum = 86400000 / 20;
            
int num = 0;
            timer 
= new System.Timers.Timer(interval);
            timer.Elapsed 
+= (o1, e1) => {
                
string str = num.ToString();
                
byte[] buff = Encoding.ASCII.GetBytes(str);
                s.SendTo(buff, buff.Length, SocketFlags.None, ipep);
                Console.WriteLine(
string.Format("Send=>{0}", str));
                num
++;
                
if (num >= sum) num = 0;
            };
            timer.Start();

            Console.WriteLine(

"== End ==");
            Console.ReadKey();

            timer.Stop();
            s.Close();
        }

private static System.Timers.Timer timer;
    }
}

  接收端代码如下:

接收端

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;namespace WpfApplication {
    
public class TimeManager {
        
public static TimeManager Instance { get { return instance; } set { instance = value; } }
        
public int Count { get { return count; } set { count = value; } }private TimeManager() { }public void Start() {
            s 
= new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            IPEndPoint ipep 

= new IPEndPoint(IPAddress.Any, 5000);
            s.Bind(ipep);

            s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership,

new MulticastOption(IPAddress.Parse("224.1.2.3"), IPAddress.Any));new Thread(new ThreadStart(() => {
                
while (!needExit) {
                    
try {
                        
byte[] b = new byte[4];
                        s.Receive(b, 
4, SocketFlags.None);
                        
string str = Encoding.ASCII.GetString(b, 0, b.Length);
                        count 
= Convert.ToInt32(str);
                    } 
catch { }
                }
            })).Start();
        }
public void Stop() {
            needExit 
= true;
            s.Close();
        }
private static TimeManager instance = new TimeManager();
        
private int count;
        
private Socket s;
        
private bool needExit = false;
    }
}

  然后在前端,将这个时间计数作为标准来定位和显示图片,代码如下:

显示端

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Threading;
using System.Runtime.InteropServices;namespace WpfApplication {
    
/// <summary>
    
/// Interaction logic for MainWindow.xaml
    
/// </summary>
    public partial class MainWindow : Window {
        
public MainWindow() {
            InitializeComponent();
        }
private void Window_Loaded(object sender, RoutedEventArgs e) {
            FullScreen();

            TimeManager.Instance.Start();

foreach (string each in Directory.GetFiles("./")) {
                
if (System.IO.Path.GetExtension(each).ToLower() == ".jpg") {
                    files.Add(System.IO.Path.GetFullPath(each));
                }
            }
new Thread(new ThreadStart(ShowImage)).Start();
        }
private void ShowImage() {
            
if (files.Count > 0) {
                
while (!needExit) {
                    
try {
                        
int now = TimeManager.Instance.Count;
                        
int count = files.Count;
                        
int offset = now % (count * 100);
                        
int index = offset / 100;
                        
string filename = files[index];this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new EventHandler((o1, e1) => {
                            image1.Source 
= new BitmapImage(new Uri(filename));
                        }), 
nullnull);//int interval = 500 - offset % 500;
                        Thread.Sleep(20);
                    } 
catch (Exception ex) {
                        MessageBox.Show(ex.ToString());
                    }
                }
            }
        }
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
            needExit 
= true;
            TimeManager.Instance.Stop();
        }
private void Window_KeyDown(object sender, KeyEventArgs e) {
            
if (e.Key == Key.F5) {
                
if (fullscreen) {
                    PartScreen();
                } 
else {
                    FullScreen();
                }
            }
        }
private void Window_SizeChanged(object sender, SizeChangedEventArgs e) {
            
//
        }private void FullScreen() {
            
this.WindowStyle = WindowStyle.None;
            
this.WindowState = WindowState.Maximized;
            
this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
            
this.Topmost = true;
            ShowCursor(
0);
            fullscreen 
= true;
        }
private void PartScreen() {
            
//this.WindowState = lastBorder;
            
//this.Location = lastLocation;
            
//this.RenderSize = lastSize;
            
//this.Topmost = false;
            
//ShowCursor(1);
            
//fullscreen = false;
        }

        [DllImport(

"user32.dll", EntryPoint = "ShowCursor", CharSet = CharSet.Auto)]
        
public extern static void ShowCursor(int status);private List<string> files = new List<string>();
        
private bool needExit = false;
        
private bool fullscreen;
        
private Point lastLocation;
        
private Size lastSize;
        
private WindowState lastBorder;
    }
}

   然而在两个设备上测试后发现实际的效果却不尽如人意,会出现同步->A超前->同步->B超前的现象,如此摇摆;复看了一遍小白的那篇文章,发现有这样一句说明:“UDP组播是采用的无连接,数据报的连接方式,所以是不可靠的。也就是数据能不能到达接受端和数据到达的顺序都是不能保证的。”这是否说明完全依靠UDP组播的精确同步也是做不到的呢?

  To be continued...