从服务器发送一个标志给客户使用C#鼠标事件 [英] Send a flag from server to clients using c# mouse events
问题描述
我正在使用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 singleevent
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 usesync
send which you do in youraccept callback
, change themsg
with something else (saybyte[] 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 usestatic
type at all! Unlike theConsole App
in your previous question. I would even suggest you to make nothingstatic
whenever possibleQ: As it is now the code begin the server which send just the string "start" to the
clients
. How can I send thestring
message of abool
flag?A: since you use socket, you cannot really send
bool
flag so to speak. You will sendbyte[]
. But you can always check in your client implementation. If thebyte[]
is of certain value, simply change it tobool
. For instance, consider of sending just1
or0
from your server. Then in your clientendReceiveCallback
, you could simply check thedata
coming and see if it is1
then it istrue
, and if it is0
then it isfalse
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 theAsyncCallBack
A: this is
winform
, you could get rid of allstatic
var! And yes, just pass it as replacement of thenull
in yourBegin
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 theIAsyncResult.AsyncState
这篇关于从服务器发送一个标志给客户使用C#鼠标事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!