Discussion on thread and network communication in remoting

Source: Internet
Author: User

InBefore using remoting, you have always been concerned about its concurrent processing capabilities. I have written a small test. Two client threads access remote objects. One should be returned immediately, and the other should be returned after the thread is sleeping for 3 seconds. It is found that the remote calls of both threads are returned 3 seconds later.
Today, I read the remoting chapter in msdn and found the following records:
[Programming with. NET Framework->. NET remote processing overview-> channel-> Channel rules]
The remote object sharing channel. The remote object does not have a channel.
Since each client connection is processed in its own thread, a single channel can serve multiple clients at the same time.

As described in this section, the server assigns an independent thread to each client connection for processing. Therefore, the remoting server should support concurrent processing, it is unlikely that two threads will return after 3 seconds because of thread blocking.
So today, with sockmon 2005, we tracked the port and network usage in the remoting call and found that I was misled by the original test. Through tracking, I also learned some specific implementation details of remoting, some of my previously confused questions, such as when to create and destroy network connections, and so on.

First, let's take a look at my tests.Program:
This is a remote object. When I is an odd number, the thread returns after 3 seconds of sleep; otherwise, it returns immediately.

Public   Class Testclass: marshalbyrefobject {
Public   String Call ( Int I) {
Long T1 = Datetime. Now. ticks;
If (I %   2   =   1 )
System. Threading. thread. Sleep ( 3000 );
Long T2 = Datetime. Now. ticks;
Return   String . Format ( " Hello [I = {0}, t = {1}] " , I, T2 - T1 );
}
}  

Client, run (New clienttest (). Run ():

Class Clienttest {
Public   Void Run () {
Channelservices. registerchannel ( New Tcpclientchannel ());
For ( Int I =   0 ; I <   2 ; I ++ )
{
Thread t= NewThread (NewThreadstart (TEST ));
T. Start ();
}
}

Int I =   0 ;

Private   Void Test () {
Int T = I ++ ;
Testclass TC = (Testclass) activator. GetObject (
Typeof (Testclass ), " TCP: // localhost: 8086/test " );
Console. writeline (TC. Call (t ));
}
}

You can run this test program in three cases:
1. After the two threads run normally, they are almost three seconds later and return:
Hello [I = 0, T = 0] Hello [I = 1, t = 30000384]
2. Run the test program when monitoring the network with sockmon,
Messages with I = 0 are returned immediately, and messages with I = 1 are returned 3 seconds later. This result should be normal.
3. Replace the value with remotingconfiguration. Configure ("client.exe. config ").
Channelservices. registerchannel (New tcpclientchannel ());
That is to say, when using the configuration file to register the channel,
No matter whether sockmon is enabled or not, the test program results are normal, the same as 2nd cases.

These two situations are depressing. Why is the test result totally different? What does the server do? Let's take a look at the tracking data:

No. Object Thread Local
Port
Remote
Port
Operation Remarks
1 Server 4584 8086   Bind the port and start listening Occurs in channel Registration
Channelservices
. Registerchannel
2 Client 5132 2296 8086 Connect and send the request TCP: // localhost: 8086/test Occurs in remote method call
TC. Call (t), T = 0
3 Client 4276 2297 8086 Connect and send the request TCP: // localhost: 8086/test Occurs in remote method call
TC. Call (t), t = 1
4 Server 780 8086 2096 Response Message Hello [I = 0, T = 0]  
5 Client 5132 2296 8086 Hello [I = 0, T = 0]  
6 Server 780 8086 2096 Response Information
Hello [I = 1, t = 30000384]
 
7 Client 4276 2297 8086 Accepted
Hello [I = 1, t = 30000384]
 

Let's take a rough look at this process. After the server registers the channel (channelservices. registerchannel), it immediately starts listening on the specified port. Then the client starts to create the first testclass. And call its remote method call (). In this case, the client selects a new port (2296) to send a communication request to the server. Then we can see that another testclass is created in the second thread (ID: 4276) and connected to the server on the new port (2297.
So far, we can see that the very important fact is that when activator. GetObject () is executed, the network is not actually accessed.
Remoting starts to process requests to the server through network communication only when remote methods are actually called. For the Sao object activated on the server, it is precisely at this time that a remote object is created (Note: Singleton creates only one object instance globally, singlecall creates an object instance for each client. In fact, not all object instances are created at this time)

Second, the client uses different ports to communicate with the server in different threads. That is to say, two network connections are enabled. While TestingCode. In this regard, there are still some questions... In addition, for the client channel, it seems that its port cannot be specified. Every time the system ignores the specified port, other ports are enabled for communication -_-

Okay. Let's continue from No. 4. The server processes the call (0) and call (1) calls respectively. When I = 0, there is no thread sleep in the middle, so the processing time is basically 0. However, I have noticed that the server uses another thread (ID: 780) to process remote calls ). That is to say, on the server side, 4584 threads are responsible for listening, while 780 threads are also used to process customer requests. In addition, for client requests on ports 2296 and 2297, the server uses the same thread for processing!

Is it possible that:
/----- Thread
Server (4584 thread): Listen ____/---- 780 thread: responsible for contacting clienta ------- \ ----- thread B
\ ---- XXX thread: responsible for contacting clientx ------/---- thread C
\ ---- Thread d

That is to say, when the main listening thread receives requests from different clients, it opens up a new communication thread to communicate with the customer. While each communication thread is only responsible for the transmission at the network layer, and is still not responsible for the actual remote processing. Instead, it opens up new multi-thread Assignment Tasks? It seems that there is such a possibility, because the advantage is to implement real concurrent processing. No matter whether the client is single-threaded or multi-threaded, requests will be handed in immediately.

Let's change the code a little and comment out testclass. // if (I % 2 = 1) in the call () method, the result will be returned after 3 seconds if call () is called.
The test result is the same as the previous one in network tracking. However, the two HELLO messages will appear almost three seconds later. This means that the two call () Methods on the server are almost simultaneously called. However, the two client requests are still carried out in a communication thread (780) at the network layer. This proves that the above conjecture may be correct. Because the threads tracked through sockmon are only socket-related threads and cannot represent the usage of all threads. It is very likely that the remote method is completed by an unknown thread.

Let's start the last test today. Open two clients at the same time. The code is modified as follows:

Public   Class Testclass: marshalbyrefobject {
Public   String Call () {
Return String. Format ("Hello" + This. Gethashcode (). tostring ());
}
}
Class Clienttest {
Public   Void Run () {
Channelservices. registerchannel ( New Tcpclientchannel (
" Channel "   +   This . Gethashcode (). tostring (),
New Binaryclientformattersinkprovider ()));

Testclass TC = (Testclass) activator. GetObject (
Typeof (Testclass ), " TCP: // localhost: 8086/test " );
Console. writeline (TC. Call ());
}
}  

Start a server and then execute two clients.

No. Object Thread Localport Remoteport Operation
1 Server 4008 8086   Bind the port and start listening
2 Client1 2524 1174 8086 Connect and send requests
3 Server 2840 8086 1174 Response Information
4 Client1 2524 1174 8086 Accept information
5 Client2 2500 1175 8086 Connect and send requests
6 Server 2292 8086 1175 Response Information
7 Client2 2524 1174 8086 Accept information

We can see that this time the server is a listening thread (4008), and the two clients use different threads and ports, which is similar to the previous situation. However, this time, the server finally uses two different communication threads for Client1 and Client2. So how does remoting differentiate communication threads? I think it is based on the channel we registered. In the past, two threads of one client were all passed through the same tcpclientchannel. Therefore, the server uses the same communication thread. Currently, each client uses an independent channel, and the server uses different network connections.

To sum up, the server has a main thread responsible for listening on the port we specified when creating the serverchannel. When the client has a request, the server assigns an auxiliary communication thread and a dedicated network connection to each clientchannel. You can process multiple requests simultaneously on each channel.

By the way, this statement is also verified through network tracking:
Msdn: tcpchannel opens and caches the same number of connections as the threads that are sending requests to another server. The socket connection on the client will be closed 15-20 seconds after being inactive.

No. Object Thread Localport Remoteport Operation
8 Client1 2524 1174 8086 Close socket and end thread
9 Server 2840 8086 1174 Close socket and end thread
10 Client2 2500 1175 8086 Close socket and end thread
11 Server 2292 8086 1175 Close socket and end thread

After 15 seconds, the communication threads of the two channels on the server and the client are terminated.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.