Click here to Skip to main content
16,017,857 members
Please Sign up or sign in to vote.
2.00/5 (1 vote)
See more:
How can use api in c# and socket programming? please.
Posted
Updated 12-Dec-10 2:48am
v2
Comments
Sandeep Mewara 1-Jun-10 3:35am    
Which API? Can you elaborate a little more? Edit and update your question.
Sergey Alexandrovich Kryukov 10-Dec-10 12:14pm    
Yes, your question is clouded, your motivation is obscure, but -- big deal! let me try to answer...
Abdul Quader Mamun 12-Dec-10 8:48am    
Spelling Check.

1 solution

Let's assume you have the very idea of sockets, otherwise it would be hard to explain anything. The ideas of how to use sockets in .NET are simple enough, even though the seem to be hard to find -- at first.

You will need to use:
C#
using Sockets = System.Net.Sockets;
using Threads = System.Threading;
using Streams = System.IO;
using IPAddress = System.Net.IPAddress;


Now, what kind of sockets, indeed? First, you need to choose from UDP vs. TCP. Anyway, top classes to use are: Sockets::TcpListener, Sockets::TcpClient, Sockets::UdpClient. UdpClient is more simple, but "business logic" could be much more difficult. As I cannot teach you your own business logic, let's concentrate on TCP; and UDP you can learn later by yourself. TCP is the most typical use of sockets, while UDP can be reserved for much more exotic applications.

All the design of your communication layer could be built around six simple ideas:


Idea #1: With TCP you work with sessions and channels. For each session, one host on your network plays the role of server, another -- the role of client. It does not matter which side is reading or writing data (typically, both sides, using some application-level protocol you define by your code). What does matter is who is listening for a new connection is the server. Let's assume there are just one server on one side and one client on another. Then you will basically need two separate threads on server side: one is listening for new connections, another one is reading/writing data from/to all client sockets at once. Having separate threads for each remote sockets is usually a big mistake: what if there are too many of them? -- the result unpredictable (like server crash).

Note: There is not strict exact recipe which process on each host plays the role of server or client: each can implement more then one server and more than one client. Therefore, I pick up the most simple example; we shall concentrate just on two sockets on both sides and associated threads (see above).

Idea #2: Server socket is created like this:

C#
Server = new Sockets::TcpListener(IPAddress.Any, port);
Server.ExclusiveAddressUse = true;


Note use of IPAddress.Any: server does not know its own IP or remote socket IPs.
Now, it is important to understand that the same instance of TcpListener is used across two threads. No IPC primitive are needed to interlock this instance: initially sockets are designed to serve as IPC themselves (but you usually will need to use mutexes to interlock access to shared data, as always).

Idea #3: Server's listening thread should use the following call in an infinite loop:

C#
Sockets::TcpClient client = Server.AcceptTcpClient();


This call is a blocking one, so the thread will be truly sleeping in waiting for a connection, not wasting a single CPU cycle.

The variable client here represents remote client socket on server's socket. This object should be used on communication thread of the server to write or read the data. As we don't know how many remote connection to expect, all such objects should be collected in some container (I would use Queue<Sockets::TcpClient>) to be used in reading/writing the data in sequence.

Idea #4: The server's communication thread should run an infinite cycle reading and/or writing to thread obtained as

C#
NetworkStream stream = client.GetStream();


Idea #5: Client thread on client side first connects to selected remote server (selected by URL and port) then goes to infinite cycle reading and/or writing to/from remove socket in the order symmetrical to the order implemented on the server: server writes, client reads and visa versa. Pretty good policy is to confirm each chunk of data send in one direction by some confirmation code (like one special byte):

C#
Client = new Sockets::TcpClient();
Client.ExclusiveAddressUse = false;
//...try block...
Client.Connect(PublisherHostName, Port);
// loop, try block, etc...
Streams::Stream Stream = Client.GetStream();
// read/write to/from Stream (it represents remote server's stream after connection


Last idea #6:
Now the trouble is: Stream read/write operations work with arrays of byte, but you want to use some objects instead. One of the possible solutions: use System.Runtime.Serialization binary formatter -- see the description of serialization, System.SerializableAttribute and related topics.

Oh! Why I'm still writing? That's it, basically.

I would like some feedback later on. Does it help? Maybe, more detailed article is needed.

Thank you for attention.
 
Share this answer
 
v5
Comments
Toli Cuturicu 18-Dec-10 18:14pm    
SAKryukov:
Oh, if you need more samples, please look at Microsoft help on the classes I just mentioned. In v.3.5 and 4.0, those samples are quite informative yet short.
Espen Harlinn 26-Feb-11 10:56am    
Good reply - a 5
Sergey Alexandrovich Kryukov 26-Feb-11 20:04pm    
Thank you for your vote and reminding me my Answer; I'll probably reuse this one
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900