private bool SendPing(CClient client) { int lightsused = 0; lock (m_mutex) { //check if any light is used for (int i = 0; i < client.m_lights.Count; i++) { if (client.m_lights[i].GetNrUsers() > 0) { lightsused = 1; break; //if one light is used we have enough info } } } CTcpData data = new CTcpData(); data.SetData("ping " + lightsused + "\n"); if (client.m_socket.Write(data) != true) { Util.Log(client.m_socket.GetError()); return(false); } return(true); }
private bool SendLights(CClient client) { CTcpData data = new CTcpData(); //build up messages by appending to CTcpData data.SetData("lights " + client.m_lights.Count + "\n"); for (int i = 0; i < client.m_lights.Count; i++) { data.SetData("light " + client.m_lights[i].Name + " ", true); data.SetData("scan ", true); data.SetData(client.m_lights[i].GetVscan()[0].ToString(Util.NumbersFormat) + " ", true); data.SetData(client.m_lights[i].GetVscan()[1].ToString(Util.NumbersFormat) + " ", true); data.SetData(client.m_lights[i].GetHscan()[0].ToString(Util.NumbersFormat) + " ", true); data.SetData(client.m_lights[i].GetHscan()[1].ToString(Util.NumbersFormat), true); data.SetData("\n", true); } if (client.m_socket.Write(data) != true) { Util.Log(client.m_socket.GetError()); return(false); } return(true); }
private bool ParseGet(CClient client, CMessage message) { CTcpData data = new CTcpData(); string messagekey; if (!Util.GetWord(ref message.message, out messagekey)) { Util.LogError($"{client.m_socket.Address}:{client.m_socket.Port} sent gibberish"); return(false); } if (messagekey == "version") { Util.Log($"{client.m_socket.Address}:{client.m_socket.Port} said get version"); return(SendVersion(client)); } else if (messagekey == "lights") { Util.Log($"{client.m_socket.Address}:{client.m_socket.Port} said get lights"); return(SendLights(client)); } else { Util.LogError($"{client.m_socket.Address}:{client.m_socket.Port} sent gibberish"); return(false); } }
internal bool Write(CTcpData data) { if (m_sock == null) { m_error = "socket closed"; return(false); } int bytestowrite = data.GetSize(); int byteswritten = 0; //loop until we've written all bytes while (byteswritten < bytestowrite) { //wait until socket becomes writeable bool returnv = WaitForSocket(true, "Write"); if (!returnv) { return(returnv); } int size = m_sock.Send(data.GetData(), byteswritten, data.GetSize() - byteswritten, SocketFlags.None, out SocketError sockError); if (size == -1) { m_error = "send() " + m_address + ":" + m_port + " " + sockError; return(false); } byteswritten += size; } return(true); }
internal bool Read(CTcpData data) { byte[] buff = new byte[1000]; if (m_sock == null) { m_error = "socket closed"; return(false); } bool returnv = WaitForSocket(false, "Read");//wait until the socket has something to read if (!returnv) { return(returnv); } //clear the tcpdata data.Clear(); //loop until the socket has nothing more in its buffer while (true) { try { int size = m_sock.Receive(buff, 0, buff.Length, SocketFlags.None, out SocketError errorCode); // recv(m_sock, buff, sizeof(buff), 0); if (errorCode == SocketError.TryAgain && size == -1) //we're done here, no more data, the call to WaitForSocket made sure there was at least some data to read { return(true); } else if (size == -1) //socket had an error { //m_error = "recv() " + m_address + ":" + m_port + " " + GetErrno(); return(false); } else if (size == 0 && data.GetSize() == 0) //socket closed and no data received { m_error = m_address + ":" + m_port + " Connection closed"; return(false); } else if (size == 0) //socket closed but data received { return(true); } data.SetData(buff, size, true); //append the data } catch (SocketException sockEx) { m_error = "receive() " + m_address + ":" + m_port + " " + sockEx.NativeErrorCode + " " + sockEx.SocketErrorCode; //TODO: format this better return(false); } } }
private bool ParseMessage(CClient client, CMessage message) { CTcpData data = new CTcpData(); string messagekey; //an empty message is invalid if (!Util.GetWord(ref message.message, out messagekey)) { Util.LogError($"{client.m_socket.Address}:{client.m_socket.Port} sent gibberish"); return(false); } if (messagekey == "hello") { Util.Log($"{client.m_socket.Address}:{client.m_socket.Port} said hello"); data.SetData("hello\n"); if (client.m_socket.Write(data) != true) { Util.Log(client.m_socket.GetError()); return(false); } lock (m_mutex) { if (client.m_connecttime == -1) { client.m_connecttime = message.time; } } } else if (messagekey == "ping") { return(SendPing(client)); } else if (messagekey == "get") { return(ParseGet(client, message)); } else if (messagekey == "set") { return(ParseSet(client, message)); } else if (messagekey == "sync") { return(ParseSync(client)); } else { Util.LogError($"{client.m_socket.Address}:{client.m_socket.Port} sent gibberish"); return(false); } return(true); }
private bool SendVersion(CClient client) { CTcpData data = new CTcpData(); data.SetData("version " + ProtocolVersion.Version + "\n"); if (client.m_socket.Write(data) != true) { Util.Log(client.m_socket.GetError()); return(false); } return(true); }
private void AddClient(CClient client) { //TODO: google this const int FD_SETSIZE = 100; lock (m_mutex) { if (m_clients.Count >= FD_SETSIZE) //maximum number of clients reached { Util.LogError($"number of clients reached maximum {FD_SETSIZE}"); CTcpData data = new CTcpData(); data.SetData("full\n"); client.m_socket.Write(data); client = null; return; } //assign lights and put the pointer in the clients vector client.InitLights(m_lights); m_clients.Add(client); } }
public void Process() { //open listening socket if it's not already if (!m_socket.IsOpen) { string liseningAddress = String.IsNullOrEmpty(m_address) ? "*" : m_address; Util.Log($"opening listening socket on {liseningAddress}:{m_port}"); if (!m_socket.Open(m_address, m_port, 1000000)) { Util.LogError($"{m_socket.GetError()}"); m_socket.Close(); } } //see if there's a socket we can read from IList <Socket> sockets = GetReadableFd(); foreach (Socket sock in sockets) { if (sock == m_socket.GetSock()) //we can read from the listening socket { CClient client = new CClient(); bool returnv = m_socket.Accept(client.m_socket); if (returnv) { Util.Log($"{client.m_socket.Address}:{client.m_socket.Port} connected"); AddClient(client); } else { client.Dispose(); client = null; Util.Log(m_socket.GetError()); } } else { //get the client the sock fd belongs to CClient client = GetClientFromSock(sock); if (client == null) //guess it belongs to nobody { continue; } //try to read data from the client CTcpData data = new CTcpData(); bool returnv = client.m_socket.Read(data); if (!returnv) { //socket broke probably Util.Log(client.m_socket.GetError()); RemoveClient(client); continue; } //add data to the messagequeue client.m_messagequeue.AddData(data.GetData(), data.GetSize()); //check messages from the messaqueue and parse them, if it fails remove the client if (!HandleMessages(client)) { RemoveClient(client); } } } }