A most basic TCT connection is established with the code below:

// Initialization
IPEndPoint m_IpEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.71"), 5000);
Socket m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
NetworkStream m_Stream = new NetworkStream(m_Socket);

// Read/write operations
m_Stream.Write(System.Text.Encoding.ASCII.GetBytes("Hello world!"), 0, 12);
byte[] read_buffer = new byte[4096];
m_Stream.Read(read_buffer, 0, 4096);

// Closing open resources
m_Stream.Close();
m_Socket.Shutdown(SocketShutdown.Both);
m_Socket.Close();

When communicating through TCP we specify both local and foregn sockets, right? Correct me if I'm wrong, this is my first network program.

I want to ask these question:
What does "127.0.0.71:5000" specify in my code? Is it local or foreign socket address? If it is local, how can I specify the foreign one (and vice versa)?

Looking for your reply.

In your case, you haven't done anything with the IPEndPoint instance, so it depends.

If you want to connect to a remote client (the rest of your code appears as such), you need to issue the "Connect" call from the socket, using the IPEndPoint instance:

m_socket.Connect(m_IpEndPoint);

right after line 3 in your post (of course, you will also put this into a try/catch block in case of exceptions). This will connect your program to the end point described by host IP "127.0.0.71", on port "5000" (which answers your question - in this case, it's a foreign - or remote - address).

Now, the IPEndPoint can refer to a local address and port, if you were to do something like this, after line 3 in your code:

m_socket.Bind(m_IpEndPoint);
m_socket.Listen(10);
Socket m_client = m_socket.Accept();

assuming your machine's IP address is "127.0.0.71", this code would set up a listen on port 5000 so other programs could establish a connection to this process (again, you will enclose this code in a try/catch block to grab any exceptions). You would have to change the rest of your code to use "m_client", as this will be the object pointing to the socket a remote client would actually be "attached" to, for you to perform your reads/writes.

m_IpEndPointForeign = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5001);
m_IpEndPointLocal = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4999);

m_SocketForeign = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
m_SocketForeign.Connect(m_IpEndPointForeign);

m_SocketLocal.Bind(m_IpEndPointLocal);
m_SocketLocal.Listen(4999);
m_SocketLocal = m_SocketForeign.Accept();

m_Stream = new NetworkStream(m_SocketLocal);

// Read & Write operations
// m_Stream.Write();
// m_Stream.Read();

m_Stream.Close();
m_SocketForeign.Shutdown(SocketShutdown.Both);
m_SocketForeign.Close();
m_SocketLocal.Shutdown(SocketShutdown.Both);
m_SocketLocal.Close();

Thank you very much for your reply. I modified my code according to your instructions as you see above.
Now I'm using the IP address 127.0.0.1 for both end points.
Local machine uses port 4999, and foreign machine uses port 5001.

I will try it now...
Thank you again.

Unfortunately the code above is not working (gives run-time error), the problem is obvious if you look carefully.

At line #7, m_SocketLocal.Bind(m_IpEndPointLocal); is used for the first time, but m_SocketLocal is not defined.

So, how can I fix this?

Well, first, is this program the client or the server? To really run it with two processes, you'll want one program to be the client, and another to be the server.

The server program should execute the Bind, Listen and Accept; while the client program executes the Connect method to connect to the server program. You appear to be doing both in the same program. You can actually do that...

In the server program, you need a local Socket object to perform the Bind and Listen. You also perform the Accept (this is where the server "comes alive" when a remote client connects to it), and the return value from the Accept is *another* socket - the socket to the remote client that just connected. The original socket can then go back to the Listen and wait for another client to connect.

When you have the programs separated, execute the server program first, then execute the client. If coded correctly, the client will connect up and you will be able to pass data back and forth.

Client:

m_IpEndPointForeign = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5000);

m_SocketForeign = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
m_SocketForeign.Connect(m_IpEndPointForeign);

m_Stream = new NetworkStream(m_SocketForeign);

// Read & Write operations
m_Stream.Write(...);  // Implementation left to you...

m_Stream.Close();
m_SocketForeign.Shutdown(SocketShutdown.Both);
m_SocketForeign.Close();

Server:

m_IpEndPointLocal = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5000);

m_SocketLocal = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

m_SocketLocal.Bind(m_IpEndPointLocal);
m_SocketLocal.Listen(10);
Socket m_SocketClient = m_SocketLocal.Accept();

m_Stream = new NetworkStream(m_SocketClient);

// Read & Write operations
m_Stream.Read();   // Actual Read() implementation left to coder...

m_Stream.Close();
m_SocketClient.Shutdown(SocketShutdown.Both);
m_SocketClient.Close();
m_SocketLocal.Shutdown(SocketShutdown.Both);
m_SocketLocal.Close();

Notice that the client and server are using the same port.

The parameter to Listen() is the number of buffered connections the Listen command will handle. That is, up to 10 clients can be "buffered" up, awaiting connection. The 11th client that attempts (assuming the server program is not fast enough to accept the connection requests) will be turned away with an error (an error, of course, that the client program should be checking for!)

For reading and writing on NetworkStream objects, investigate the StreamReader and StreamWriter classes...

Thank you very much for your wonderful explanation.
I will try this code tomorrow morning.

What I'm trying to do is to write a simulator. There is a hardware in the project I'm working on, it works under TCP protocol, regularly sends several bytes of data through port 5001. My code will simulate this device, by sending data to the port 5001.

The only difference between server and client sides are that, the server "listens (by Listen() method)" if any clients are available, if there is, "accepts (by Accept() method)" them. The client "writes" the data, and then waits until the reply delivers. Is that so?

Yep, that's pretty much it.

Something got in my mind,

Why does the server specify an IP address to create a local socket? The IP address of the local machine can not be chosen arbitrarily, isn't it? If the local machine is connected to a network, it must already have a unique IP address, so why do we specify an IP address even though there is already one.

Is this for choosing a connection for PCs which have more that one network adapters, or for implementing something like "remote-server"?

Good point, you can specify an IP address for the server manually (like was done in the example), or, you can use this syntax:

m_IpEndPointLocal = new IPEndPoint(IPAddress.Any, 5000);

This would cause the default adapter to be used. To your point, if your machine has more than one network adapter, then by specifying the IP address manually, you can "nail down" the socket to a specific adapter.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.