0

I have a solution with two projects which act as Server and Client respectively. The Client is a simple console application which sends data to the server. The server is a WPF application which receives the data and displays it in a datagrid. The MVVM approach is used here.

In the Server UI there are three textboxes in which the user can type in:

IP Address: ("127.0.0.1")

Port: (some port)

Delimeter: (some char like '@' for example)

The challenge for me in this one is that, whatever delimeter the user provides, it should be used in the client project, to be put in between the data which is to be sent. For example the client sends:

Name + Delimeter + Surname + Delimeter + Age

What i have tried:

I added a Utils class with static fields for IPAddress, port and delimeter like this:

public class Utils
{
    public static string IP_ADDRESS = " ";
    public static int PORT = 0;
    public static char DELIMETER = '\0';

}

I then tried to change these values in my ViewModel where the respective properties which are bound to the UI are by assigning them:

private void storeData()
{
    Utils.IP_ADDRESS = IP;
    Utils.PORT = Port;
    Utils.DELIMETER = Delimeter;
}

In the client program:

static void Main(string[] args)
    {
        Client client = new Client(Utils.IP_ADDRESS, Utils.PORT);

        while (true)
        {
            client.SendData("some Name" + Utils.DELIMETER + "some Surname" +  Utils.DELIMETER + some Age + Utils.DELIMETER + "something else");
            Thread.Sleep(3000);
        }
    }

The problem here is that whenever i start a new Client instance the values from the util class are still the default ones (null).

Any help is appreciated.

20
  • 2
    You should use a configuration file and read/write the shared variables (IP_ADDRESS, PORT, DELIMITER) from/into this file. Commented Feb 7, 2017 at 20:33
  • 1
    You could use the same form on the client that you're using on the server, or read the connection info from a config file. Commented Feb 7, 2017 at 20:35
  • 1
    No need for a config file. When a client connects to the server, there should be a short negotiation: the server sends the delimiter on client connect (just a writeline of the delimiter), the client would read and store the delimiter after a connection (just a readline after the connection). Commented Feb 7, 2017 at 20:37
  • 1
    @AdamSills if the client don't know the server IP address and port there is no way to make any negotiation. Commented Feb 7, 2017 at 20:42
  • 1
    IP Addresses and Ports are details that are needed for the client to communicate to the server. You want the client to get this information from the server before communicating? That's impossible. You will need to send this information to the clients some way, and whatever way you used to send that information is more robust than your client/server communication, so that means you're effectively short-circuiting yourself. Commented Feb 7, 2017 at 20:43

2 Answers 2

1

Let's break down your problem:

  1. The server can change ip or ports at will and the clients will somehow guess the new port and connect.
  2. The server changes the delimiter at will and the clients adapt to the new delimiter.

Problem 1 is impossible. Information cannot magically get transferred to clients before the client connects to the server, and the client needs ip and ports to connect to the server. Whatever technique you use to transfer the ip and port to the client is a better communication channel than your client/server, so you don't need a client/server.

Problem 2 has been solved by WCF already. Use WCF and SOAP or REST (which is just HTML).

Here is a sample of what the code would look like for the clients to determine the delimiter before sending the main request:

class Server
{
    private TcpListener _listener = new TcpListener(12312);            
    public void Start()
    {
        _listener.Start();
        while (true)
        {
            var client = _listener.AcceptTcpClient();
            var stream = client.GetStream();
            var request = getRequest(stream);
            if (request == "GetDelimiter")
            {
                SendResponse(Utils.DELIMITER, stream);
            }
            else
            {
                ProcessNameSurnameAge(request);
            }
        }
    }
}

class Client
{
    private TcpClient _client = new TcpClient();
    public void DoTheThing()
    {
        _client.Connect("127.0.0.1", 12312);
        var stream = _client.GetStream();
        SendRequest("GetDelimiter", stream);
        var delimiter = GetResponse(stream);
        var newRequest = "some Name" + delimiter + "some Surname" + delimiter + "some Age" + delimiter + "something else";
        SendRequest(newRequest);
    }
}

Note that I skip over the encoding details of sending data over TCP because it seems like you've already got a handle on that.

Sign up to request clarification or add additional context in comments.

5 Comments

First, thank you for your answer and effort. Second it is not inteded to change the values of ip address, port and delimeter continuously as the application is running. Once the values are set they don't need to change. Lastly, i have never used WCF before, and i am looking for a solution only using WPF.
I strongly suggest you learn WCF as that is .Net's solution to your problem. You are reinventing the wheel.
As for ip and port, the server cannot communicate that information to clients before the clients connect. That is not possible using TCP.
Would it not be possible to store the values for ip and port into some variables, and then use those variables in the class where i declare the client(which is in another project), as parameters to the client constructor? Client client = new Client(string ip, int port)
No that's not possible. Your client and server are 2 different processes, and processes cannot share their variables. This is the reason for TCP to exist in the first place. WCF is Microsoft's solution to precisely the problem you are facing. Note that projects and processes are 2 different things, but in your case each project ends up being a single process.
0

I was able to solve this in a rather simple manner. Steps i used to solve are as follow:

In the server:

  1. Created a text file in my solution.
  2. When the server starts in my view model, i saved the properties ip, port and delimeter in a string array.
  3. Next i used the IO File class to write the content of the array in the text file.

In the client:

  1. First i read from the file.
  2. Next i created the client instance and passed the ip and port as parameters to it's constructor.

Thank you D Stanley and Damian Galletini for your suggestions. Also thank you everybody else who tried to help.

3 Comments

You are using the filesystem as your communication channel. The file system is much better than your client server, so you don't need a client server.
Agreed, but the assignment specifies that tcp communication between a server and many clients should be implemented.
I understand much better now. StackOverflow is dedicated to solve real problems. It is the site's policy to explicitely state when the question is about homework, as that usually involves arbitrary constraints, such as yours.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.