从服务器发送一个标志给客户使用C#鼠标事件 [英] Send a flag from server to clients using c# mouse events

查看:118
本文介绍了从服务器发送一个标志给客户使用C#鼠标事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用C#插座,以便从服务器发送数据到客户机上。事实上,我已经创建了3种不同的机器capature的Kinect流的捕捉。我想生成一个服务器和客户沟通,以从服务器发送信号到其他设备,以便开始和停止录制过程。我想用左键点击发送消息到开始录制,并右键单击停止录制。我的code是以下内容:

 公共Form1中()
{
    的InitializeComponent();
    this.MouseClick + = mouseClick1;
    线程线程=新主题(()=> startserver的(消息));
    thread.Start(); //服务器开始时
}私人无效mouseClick1(对象发件人,MouseEventArgs E)
{    如果(e.Button == MouseButtons.Left)
    {
       =开始消息;
        尝试
        {
                OBJ =新的捕食者(dirPath +名称+_+姓,20);
        }
        赶上(例外E1)
        {
            Console.WriteLine(这个过程失败:{0},e1.ToString());
        }
        如果(clientSockets.Count大于0)
        {
            Thread.sleep代码(10);
            的foreach(在clientSockets插座SOCKET1)
                socket1.Send(Encoding.ASCII.GetBytes(消息)); //发送一切给所有客户端的字节
        }
        其他
        {            serverSocket.BeginAccept(新的AsyncCallback(acceptCallback),NULL); //接收其他客户端
        }    }
    否则,如果(e.Button == MouseButtons.Right)
    {
        消息=停止;
        obj.flag2 = TRUE;        如果(clientSockets.Count大于0)
        {
            Thread.sleep代码(10);
            的foreach(在clientSockets插座SOCKET1)
                socket1.Send(Encoding.ASCII.GetBytes(消息)); //发送一切给所有客户端的字节
        }
        其他
        {            serverSocket.BeginAccept(新的AsyncCallback(acceptCallback),NULL); //接收其他客户端
        }
    }
}公共无效的startserver(字符串消息){    ServerSocket的=新的Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
    serverSocket.Bind(新IPEndPoint(IPAddress.Any,PORT_NO));
    serverSocket.Listen(4); //最大的待处理的客户,定义如你所愿
    serverSocket.BeginAccept(新的AsyncCallback(acceptCallback),NULL);
    字符串结果=;
    做
    {
        结果=ASDF;
    }而(result.ToLower()修剪()=退出。!);
}
私人const int的BUFFER_SIZE = 4096;
私人静态的byte []缓冲区=新的字节[BUFFER_SIZE]; //缓冲区大小被限制每个消息BUFFER_SIZE
私人静态列表<插座及GT; clientSockets =新的List<插座及GT;(); //可能你需要
私有静态无效acceptCallback(IAsyncResult的结果)
{//如果缓冲区是旧的,那么有可能已经存在的东西...
    Socket套接字= NULL;
    尝试
    {        插座= serverSocket.EndAccept(结果); //本的ObjectDisposedException会来这里......因此,可以预期的!
        //做一些事情,你看到它需要在客户验收
        clientSockets.Add(插座);
        socket.BeginReceive(缓冲,0,buffer.Length,SocketFlags.None,新的AsyncCallback(receiveCallback),插座);
        弦乐味精=开始;
        //socket.Send(Encoding.ASCII.GetBytes(msg));        如果(clientSockets.Count大于0)
        {
            Thread.sleep代码(10);
            的foreach(在clientSockets插座SOCKET1)
                socket1.Send(Encoding.ASCII.GetBytes(MSG)); //发送一切给所有客户端的字节
        }
        其他
        {            serverSocket.BeginAccept(新的AsyncCallback(acceptCallback),NULL); //接收其他客户端
        }
    }
    赶上(例外五)
    {//这个异常时会发生本是处置......
        //这里做什么
        Console.WriteLine(e.ToString());
    }
}const int的MAX_RECEIVE_ATTEMPT = 10;
静态INT receiveAttempt = 0; //这是骗不了的证据,很明显,因为其实你必须为多个客户端的这个倍数,但为了简单起见,我把这个
私有静态无效receiveCallback(IAsyncResult的结果)
{
    Socket套接字= NULL;
    尝试
    {
        插座=(插座)result.AsyncState; //这是获得发送方
        如果(socket.Connected)
        {//简单的检查
            INT收到= socket.EndReceive(结果);
            如果(接收大于0)
            {
                字节[]数据=新的字节[收] //中的数据是在字节[]格式,而不是串!
                Buffer.BlockCopy(缓冲液,0,数据,0,data.Length); //有几个这样的方式根据http://stackoverflow.com/questions/5099604/any-faster-way-of-copying-arrays-in-c一般做,System.Buffer.memcpyimpl是最快
                //做一些事情上的数据INT的byte [] !! Yihaa!
                Console.WriteLine(Encoding.UTF8.GetString(数据)); //这里我只是打印出来,但你需要做别的事情                //信息检索部分
                //假设你只需要声明的是从客户端接收数据到客户端
                弦乐味精=我收到你的留言:+ DateTime.Now;
                socket.Send(Encoding.ASCII.GetBytes(MSG)); //请注意,您实际上是在字节的发送数据[]
                Console.WriteLine(我发这个消息给客户端:+味精);                receiveAttempt = 0; //复位收到尝试
                //socket.BeginReceive(buffer,0,buffer.Length,SocketFlags.None,新的AsyncCallback(receiveCallback),插座); //重复beginReceive
            }
            否则,如果(receiveAttempt< MAX_RECEIVE_ATTEMPT)
            {//失败,但不超过最大尝试,重复
                ++ receiveAttempt; //增加接收尝试;
                socket.BeginReceive(缓冲,0,buffer.Length,SocketFlags.None,新的AsyncCallback(receiveCallback),插座); //重复beginReceive
            }
            其他
            {//完全失效!
                Console.WriteLine(receiveCallback失败!); //不要重复beginReceive
                receiveAttempt = 0; //重置此为下一次连接
            }
        }
    }
    赶上(例外五)
    {//这个异常时会发生本是处置......
        Console.WriteLine(receiveCallback失败,异常!+ e.ToString());
    }
}

我如何解析标志到服务器,以便发送在客户端的价值?是否有可能改变这里的静态类型的服务器功能?因为它是现在的code开始发送这只是字符串启动到客户端的服务器。我如何发送一个布尔标志的字符串消息?我的问题在于静态类型的我的回调函数。是否有可能在AsyncCallback的添加作为参数的消息,例如:

  serverSocket.BeginAccept(新的AsyncCallback(acceptCallback),NULL);


解决方案

首先,有关鼠标点击事件。既然你有独家作为事件的资格(即一个左击,另一右键),你可以将它们都合并成一个单一的事件

 公共Form1中()
{
    的InitializeComponent();
    this.MouseClick + = mouseClick1; //一个事件就足够了    线程线程=新主题(()=> startserver的(消息));
    thread.Start(); //服务器开始时
}私人无效mouseClick1(对象发件人,MouseEventArgs E)
{
    如果(e.Button == MouseButtons.Left)
    {
        尝试
        {
            OBJ =新的捕食者(dirPath +名称+_+姓,20); //捕捉Kinect的流
        }
        赶上(例外E1)
        {
            Console.WriteLine(这个过程失败:{0},e1.ToString());
        }
    }
    否则,如果(e.Button == MouseButtons.Right)
    {
        obj.flag2 = TRUE; //该处理记录标志,真值停止记录,可能我想这个值被发送到客户端,以同样的事情发生。
    }
}

和这将是确定。

接下来,回答你的问题:


  

问:我怎样才能解析标志到服务器,以发送值
  在客户端?


  
  

答:在你的 mouseClick1 时,只需使用同步发送,你做你的接受回调,修改信息用别的东西(比如字节[] VAL =新的字节[] {1} ;

 的foreach(在clientSockets插座SOCKET1)//在`如果(e.Button == Mouse.Left和Mouse.Right)模块执行此操作
    socket1.Send(Encoding.ASCII.GetBytes(MSG));


  
  

问:是否可以更改此处的静态类型的服务器功能?


  
  

答:是的,绝对!这是 windows窗体,你并不需要使用静态
  请在所有!不同于控制台应用程序在previous问题。我会
  甚至建议你做什么静态尽可能


  
  

问:由于这是现在code开始发送这只是字符串服务器
  开始的客户。我怎样才能发送字符串的消息布尔
  标志?


  
  

答:既然你使用套接字,你真的不能发送布尔标记,以便于
  说话。您将发送字节[] 。但是,你可以随时查询您的
  客户端实现。如果字节[] 是一定值时,只需
  将其更改为布尔。例如,考虑仅发送的 1 0
  从您的服务器。然后在你的客户端 endReceiveCallback ,你可以
  简单地检查数据来,看看它是否是 1 则是真正
  如果是 0 则是


  
  

问:我的问题出在静态类型的我的回调函数。是吗
  可以添加作为参数的消息,例如在
  的AsyncCallback


  
  

答:这是的winform ,你可以摆脱所有的静态变种!是的,
  只是把它作为你的开始 回调空 >。
  然后,你传递对象了。

  //改变null与别的东西
serverSocket.BeginAccept(新的AsyncCallback(acceptCallback),MyObj中);


  
  

然后在你的 acceptCallback ,把你的对象使用 IAsyncResult.AsyncState


I am using sockets in c# in order to send data from server to client machine. In fact I have created a capturer which capature kinect stream from 3 different machine. I want to generate a server and client communication in order to send signal from server to the rest devices in order to begin and stop the recording process. I want with left click to send a message to begin recording and with right click to stop recording. My code is the following:

public Form1()
{
    InitializeComponent();
    this.MouseClick += mouseClick1;


    Thread thread = new Thread(() => StartServer(message));
    thread.Start();  // server is begining
}

private void mouseClick1(object sender, MouseEventArgs e)
{

    if (e.Button == MouseButtons.Left)
    {
       message = "start";  
        try
        {
                obj = new Capturer(dirPath + name + "_" + surname, 20);
        }
        catch (Exception e1)
        {
            Console.WriteLine("The process failed: {0}", e1.ToString());
        }
        if (clientSockets.Count > 0)
        {
            Thread.Sleep(10);
            foreach (Socket socket1 in clientSockets)
                socket1.Send(Encoding.ASCII.GetBytes(message)); //send everything to all clients as bytes
        }
        else
        {

            serverSocket.BeginAccept(new AsyncCallback(acceptCallback), null); //to receive another client
        }

    }
    else if (e.Button == MouseButtons.Right)
    {
        message = "stop";
        obj.flag2 = true;

        if (clientSockets.Count > 0)
        {
            Thread.Sleep(10);
            foreach (Socket socket1 in clientSockets)
                socket1.Send(Encoding.ASCII.GetBytes(message)); //send everything to all clients as bytes
        }
        else
        {

            serverSocket.BeginAccept(new AsyncCallback(acceptCallback), null); //to receive another client
        }
    }
}

public void StartServer(String message) {

    serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    serverSocket.Bind(new IPEndPoint(IPAddress.Any, PORT_NO));
    serverSocket.Listen(4); //the maximum pending client, define as you wish
    serverSocket.BeginAccept(new AsyncCallback(acceptCallback), null);
    string result = "";
    do
    {
        result ="asdf";
    } while (result.ToLower().Trim() != "exit");
}
private const int BUFFER_SIZE = 4096;
private static byte[] buffer = new byte[BUFFER_SIZE]; //buffer size is limited to BUFFER_SIZE per message
private static List<Socket> clientSockets = new List<Socket>(); //may be needed by you 
private static void acceptCallback(IAsyncResult result)
{ //if the buffer is old, then there might already be something there...
    Socket socket = null;
    try
    {

        socket = serverSocket.EndAccept(result); // The objectDisposedException will come here... thus, it is to be expected!
        //Do something as you see it needs on client acceptance
        clientSockets.Add(socket);
        socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(receiveCallback), socket);


        string msg = "start";
        //socket.Send(Encoding.ASCII.GetBytes(msg));

        if (clientSockets.Count > 0)
        {
            Thread.Sleep(10);
            foreach (Socket socket1 in clientSockets)
                socket1.Send(Encoding.ASCII.GetBytes(msg)); //send everything to all clients as bytes
        }
        else
        {

            serverSocket.BeginAccept(new AsyncCallback(acceptCallback), null); //to receive another client
        }
    }
    catch (Exception e)
    { // this exception will happen when "this" is be disposed...        
        //Do something here             
        Console.WriteLine(e.ToString());
    }
}

const int MAX_RECEIVE_ATTEMPT = 10;
static int receiveAttempt = 0; //this is not fool proof, obviously, since actually you must have multiple of this for multiple clients, but for the sake of simplicity I put this
private static void receiveCallback(IAsyncResult result)
{
    Socket socket = null;
    try
    {
        socket = (Socket)result.AsyncState; //this is to get the sender
        if (socket.Connected)
        { //simple checking
            int received = socket.EndReceive(result);
            if (received > 0)
            {
                byte[] data = new byte[received]; //the data is in the byte[] format, not string!
                Buffer.BlockCopy(buffer, 0, data, 0, data.Length); //There are several way to do this according to http://stackoverflow.com/questions/5099604/any-faster-way-of-copying-arrays-in-c in general, System.Buffer.memcpyimpl is the fastest
                //DO SOMETHING ON THE DATA int byte[]!! Yihaa!!
                Console.WriteLine(Encoding.UTF8.GetString(data)); //Here I just print it, but you need to do something else                     

                //Message retrieval part
                //Suppose you only want to declare that you receive data from a client to that client
                string msg = "I receive your message on: " + DateTime.Now;
                socket.Send(Encoding.ASCII.GetBytes(msg)); //Note that you actually send data in byte[]
                Console.WriteLine("I sent this message to the client: " + msg);

                receiveAttempt = 0; //reset receive attempt
                //socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(receiveCallback), socket); //repeat beginReceive
            }
            else if (receiveAttempt < MAX_RECEIVE_ATTEMPT)
            { //fail but not exceeding max attempt, repeats
                ++receiveAttempt; //increase receive attempt;
                socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(receiveCallback), socket); //repeat beginReceive
            }
            else
            { //completely fails!
                Console.WriteLine("receiveCallback fails!"); //don't repeat beginReceive
                receiveAttempt = 0; //reset this for the next connection
            }
        }
    }
    catch (Exception e)
    { // this exception will happen when "this" is be disposed...
        Console.WriteLine("receiveCallback fails with exception! " + e.ToString());
    }
}

How can I parse the flag into the server, in order to send that value in the clients? Is it possible to change here the static type of server functions? As it is now the code begin the server which send just the string "start" to the clients. How can I send the string message of a bool flag? My issue lies in the static type of my callback functions. Is it possible to add as an argument the message for example in the AsyncCallBack:

serverSocket.BeginAccept(new AsyncCallback(acceptCallback), null); 

解决方案

Firstly, about the MouseClick event. Since you are having exclusive qualification for the event (that is, one left click and another right click), you could combine them both into a single event

public Form1()
{
    InitializeComponent();
    this.MouseClick += mouseClick1; //one event is enough

    Thread thread = new Thread(() => StartServer(message));
    thread.Start();  // server is begining
}

private void mouseClick1(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        try
        {
            obj = new Capturer(dirPath + name + "_" + surname, 20); //captures the kinect streams
        }
        catch (Exception e1)
        {
            Console.WriteLine("The process failed: {0}", e1.ToString());
        }
    } 
    else if (e.Button == MouseButtons.Right)
    {
        obj.flag2 = true; // flag that handle the recording, true value stops the recording, possible I want that value to be send to the client in order the same thing happen.
    }
}

And it is going to be ok.

Next, answering your questions:

Q: How can I parse the flag into the server, in order to send that value in the clients?

A: in your mouseClick1 event, simply use sync send which you do in your accept callback, change the msg with something else (say byte[] val = new byte[] { 1 };)

foreach (Socket socket1 in clientSockets) //Do this in your `if (e.Button == Mouse.Left and Mouse.Right) blocks
    socket1.Send(Encoding.ASCII.GetBytes(msg));

Q: Is it possible to change here the static type of server functions?

A: Yes, definitely! it is windows form, you do not need to use static type at all! Unlike the Console App in your previous question. I would even suggest you to make nothing static whenever possible

Q: As it is now the code begin the server which send just the string "start" to the clients. How can I send the string message of a bool flag?

A: since you use socket, you cannot really send bool flag so to speak. You will send byte[]. But you can always check in your client implementation. If the byte[] is of certain value, simply change it to bool. For instance, consider of sending just 1 or 0 from your server. Then in your client endReceiveCallback, you could simply check the data coming and see if it is 1 then it is true, and if it is 0 then it is false

Q: My issue lies in the static type of my callback functions. Is it possible to add as an argument the message for example in the AsyncCallBack

A: this is winform, you could get rid of all static var! And yes, just pass it as replacement of the null in your Begin callback. Then you pass the object too.

//Change null with something else
serverSocket.BeginAccept(new AsyncCallback(acceptCallback), myobj);

Then in your acceptCallback, take your object by using the IAsyncResult.AsyncState

这篇关于从服务器发送一个标志给客户使用C#鼠标事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆