0

I have a C# script that connects to the Server and sends/receives some commands and responses.

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
using System.Collections;

// State object for receiving data from remote device.  
public class StateObject
{
    // Size of receive buffer.  
    public const int BufferSize = 256;

    // Receive buffer.  
    public byte[] buffer = new byte[BufferSize];

    // Received data string.  
    public StringBuilder sb = new StringBuilder();

    // Client socket.  
    public Socket workSocket;
}

public class AsynchronousClient : MonoBehaviour
{

    public GameObject chatContainer;
    public GameObject messagePrefab;

    // The port number for the remote device.  
    private const int port = 5002;

    // ManualResetEvent instances signal completion.  
    private static readonly ManualResetEvent connectDone =
        new ManualResetEvent(false);

    private static readonly ManualResetEvent sendDone =
        new ManualResetEvent(false);

    private static readonly ManualResetEvent receiveDone =
        new ManualResetEvent(false);

    // The response from the remote device.  
    private static string response = string.Empty;

    public void StartClient()
    {

        // Connect to a remote device.  
        try
        {
            // Establish the remote endpoint for the socket.  


            var ipAddress = IPAddress.Parse("localhost");
            var remoteEP = new IPEndPoint(ipAddress, port);

            // Create a TCP/IP socket.  
            var client = new Socket(ipAddress.AddressFamily,
                SocketType.Stream, ProtocolType.Tcp);

            // Connect to the remote endpoint.  
            client.BeginConnect(remoteEP,
                ConnectCallback, client);
            connectDone.WaitOne();

            var data1 =
                "example request 1";
           data1 += '\0';
            var data2 =
                 "example request2";
            data2 += '\0';


            //Send test data to the remote device.  
            Send(client, data1);
          Send(client, data2);
            //sendDone.WaitOne();
           // Receive the response from the remote device.  
            Receive(client);

            // 10 saniye gozleyir sonra socket ve clienti close edir
            //receiveDone.WaitOne(1000);

            // yield return new WaitForSeconds(1);
            // Write the response to the console.  



            // Release the socket.  
            // client.Shutdown(SocketShutdown.Both);
            //client.Close();

        }
        catch (Exception e)
        {
            Debug.Log(e.ToString());


        }
    }



    private void ConnectCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the socket from the state object.  
            var client = (Socket)ar.AsyncState;

            // Complete the connection.  
            client.EndConnect(ar);

            Debug.Log("Socket connected to {0}" +
                client.RemoteEndPoint);

            // Signal that the connection has been made.  
            connectDone.Set();
        }
        catch (Exception e)
        {
            Debug.Log(e.ToString());
        }
    }

    private void Receive(Socket client)
    {
        try
        {
            // Create the state object.  
            var state = new StateObject();
            state.workSocket = client;

            // Begin receiving the data from the remote device.  
            client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                ReceiveCallback, state);
        }
        catch (Exception e)
        {
            Debug.Log(e.ToString());
        }
    }

    private void ReceiveCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the state object and the client socket   
            // from the asynchronous state object.  
            var state = (StateObject)ar.AsyncState;
            var client = state.workSocket;

            // Read data from the remote device.  
            var bytesRead = client.EndReceive(ar);

            if (bytesRead > 0)
            {
                // There might be more data, so store the data received so far.  
                string receieved = Encoding.ASCII.GetString(state.buffer, 1, bytesRead);
                state.sb.Append(receieved);
                Debug.Log(receieved);
                var ok = "returnValue=\"0\"";
                if (receieved.Contains(ok)){
                    Debug.Log("yehuuuuu");
                }
                // Get the rest of the data.  
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    ReceiveCallback, state);
            }
            else
            {
                // All the data has arrived; put it in response.  
                if (state.sb.Length > 1) response = state.sb.ToString();
                // Signal that all bytes have been received.  
                receiveDone.Set();
            }
        }
        catch (Exception e)
        {
            Debug.Log(e.ToString());
        }
    }



    private void Send(Socket client, string data)
    {
        // Convert the string data to byte data using ASCII encoding.  
        var byteData = Encoding.ASCII.GetBytes(data);

        // Begin sending the data to the remote device.  
        client.BeginSend(byteData, 0, byteData.Length, 0,
            SendCallback, client);
    }

    private void SendCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the socket from the state object.  
            var client = (Socket)ar.AsyncState;

            // Complete sending the data to the remote device.  
            var bytesSent = client.EndSend(ar);
            Debug.Log("Sent {0} bytes to server." + bytesSent);

            // Signal that all bytes have been sent.  
            sendDone.Set();
        }
        catch (Exception e)
        {
            Debug.Log(e.ToString());
        }
    }


}

I am looking for the key word (returnValue=0) in responses and according to that data I am doing if query.

private void ReceiveCallback(IAsyncResult ar)
  {
      try
      {
          // Retrieve the state object and the client socket   
          // from the asynchronous state object.  
          var state = (StateObject)ar.AsyncState;
          var client = state.workSocket;

          // Read data from the remote device.  
          var bytesRead = client.EndReceive(ar);

          if (bytesRead > 0)
          {
              // There might be more data, so store the data received so far.  
              string receieved = Encoding.ASCII.GetString(state.buffer, 1, bytesRead);
              state.sb.Append(receieved);
              //response-u konsolda yazdiran budur!!!!!!!!!!!!!!!!!!
              Debug.Log(receieved);
              var ok = "returnValue=\"0\"";
              if (receieved.Contains(ok)){
                  Debug.Log("yehuuuuu");
              }
              // Get the rest of the data.  
              client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                  ReceiveCallback, state);
          }
          else
          {
              // All the data has arrived; put it in response.  
              if (state.sb.Length > 1) response = state.sb.ToString();
              // Signal that all bytes have been received.  
              receiveDone.Set();
          }
      }
      catch (Exception e)
      {
          Debug.Log(e.ToString());
      }

But what I need to do is : I want to send/receive data to and from the server and make some conditions like "if" as above in a different file and place. So as a result I will have one file which makes general controls, and different files that sends/receives the data(also makes some queries).

I tried to call the public function in a different file using the global class but was not able to produce working result. Do I have to make new function that will allow me to send/receive the data to and from the server in any file? Any help would be highly appreciated.

  • Do you have client and server DLLs? – ChaosPandion Jan 24 '19 at 13:12
  • I dont need any DLL actually in this case. What I need is to make the send,receive function global and call it in anywhere. – Ali Mammadov Jan 24 '19 at 13:14
  • I think the close votes are about a lack of clarity. We really need a bit more understanding of your project. The question of making something global could be some kind of singleton, a static class, dependency injection. – ChaosPandion Jan 24 '19 at 13:15
  • I need to be able to use send/receive function globally in anywhere. what is not clear in here ? – Ali Mammadov Jan 24 '19 at 13:18
  • I did my best with my answer, hopefully it points you in the right direction. – ChaosPandion Jan 24 '19 at 13:26
  • The "be able to use" and "globally in anywhere". Anywhere in the class? in the same name space? in an other name space? in an other project? in an other solution? Just from anywhere like a web sercie? Be able to use : like see the function? add the Library? add a reference? add the service? – Drag and Drop Jan 24 '19 at 13:41
  • The main issue is that's it's unclear , I you were able to be clear you will by definition formulate the solution by describing the problem. I do Believe that the best answer to this is the comment from chaos : [singleton](http://csharpindepth.com/Articles/General/Singleton.aspx), a [static class](https://www.geeksforgeeks.org/c-sharp-static-class/), [dependency injection](https://stackoverflow.com/questions/14301389/why-does-one-use-dependency-injection). One of them should be your solution. – Drag and Drop Jan 24 '19 at 13:51
  • Want to use Send and Receive in another file inside of the project. in order to do that I need to make the Send and Receive function global I think therefore wrote like that. I am sending the requests to the server and in returns server sends me the answers( to the client). And I do an if statement based on that response data from the server. I just need to use 3 thing in any file in the project: 1) Send 2) Receive 3) Make an if statement – Ali Mammadov Jan 24 '19 at 13:55

1 Answers1

0

There are probably many ways to resolve so you probably will need to use your best judgement. Start by managing the client itself. You could have a static class that handles it but beware of concurrency issues.

public static class RemoteClient
{
     // Prepare and maintain
}

You can also pass the client into the objects that will use it via the constructor.

public class GameBehavior
{
    private readonly AsynchronousClient _client;

    public GameBehavior(AsynchronousClient client)
    {
        _client = client;
    }
}

Just remember that if multiple things are accessing the client you will want to have a client that supports multiple threads accessing it. The same goes for the server code. Concurrency itself is a whole sub-field of knowledge that you really need to work through from the bottom to understand.

ChaosPandion
  • 77,506
  • 18
  • 119
  • 157