He said that it is a very simple forwarding (not part of the project plan), when I thought it was very simple, not to put the received data, found the target machine according to the configuration file, and send it out? ? So I did.
1. BCB
A. In the main form, drag a TSERVERSOCKET, TCLIENTSOCKET. Define two structures, one is used to save the received information (only one of the variables of this structure), a list of configuration information used to save the target machine. Respectively
TADDR {// address information
ANSISTRING STRID;
Ansistring Strip;
Int strport;
}
TMSG {// Send content hypothesis is like this
ANSISTRING STRID;
Ansistring startle;
Ansistring StrMemo;
}
The red part is used to make a mark, when the content received is Strid, it is sent to the ADDR with Strid.
At that time, the idea was this: Define a variable TMSG GMSG; write to this place every time ServerSocket, find the corresponding addr from Addrlist and then send it with the ClientSocket.
It is very simple, it is really simple. Later, I found some shortcomings (there is no problem, there is a problem, very normal, and there is no serious study of BCB, work needs, and the idea is always deep! Today is a summary):
When the data read, there is no clientsocket to send out, the new data is coming, so there is a conflict of MSG. This conflict is not a one or two things. (Of course, there are other problems here, including several options behind, but when you take into account, then say, if there is any problem, you have a visit [Is there?] Remnant, and later found this conflict. The way is solved, with TcriticalSECTION, as the name, critical area, or Tevent event triggers, but does not completely solve the problem).
B. The head is said, the A solution is not good, use the B program! Oh, it is a chain list, or more suitable for the queue for the CLIST, naturally use TLIST in BCB, huh, huh! It's a genius, @ _ @.
When you send it, you will add it from the back of the list when you send it. I am not a master, I have made it, or there is a conflict. What should I do? At this time, I thought of multi-threaded, like a sunshine, bounced from the dark night sky, I saw hope (dizzy, so bad things also wrote). Here is a C program, huh, huh
C. At that time, there was no higher thirty to think of a multi-thread, so I thought it was received, and the address information was found from the address list. Then create a clientsocket that sends data, at this time, of course, the clientsocket on the form is useless, and each thread must use a clientsocket. This time, how long does it take to send a data? There is no impact on other data distribution. The conflict is significantly reduced, but it is still. Finally, I found this class, (Liu Huan's voice sound: 10 million miles, I pursue you ...). The conflict is mainly when the address is found from the address list, so a function is divided separately from the search address. Then gcritsect-> acquire ();
…….operating
Ccritsect-> Release ();
Correspondingly in the VC
CcriticalSECTION M_Critsect;
M_critset-> lock ();
…operating
m_critsect-> UNLOCK ();
Of course, it should be a global function, or other threads will not have an impact.
So the test, do the following environment configuration.
Machine 1
Machine 2
Machine 3
Machine N
Simulate a trigger that sends data
A-> b Arrow Represents A forwarding data to B. This will only be done in the configuration file setting. That's right, it is a loop. Send a lot of past, okay. Snoving, talking, it will die once, huh, huh.
Here is found to set freeOntterminate in the thread to true. then
Onterminate = taskthreadterminate;
You can clear the resource in the function taskthreadterminate function.
D. Finally, suddenly found. That Serversocket is not blocking. Server Type: STNONBLOCKING. Mad. There is also a stthreadblocking what is going on? It should be the so-called multi-threaded server.
After the transformation of the original procedure, it feels that its process should be as follows:
1. In an ONGETTHREAD event, the object given to the New a TServerClientThread is assumed to be TdissvrCltthread.
See the help of the help documentation, TSERVERCLIENTTHREAD, is
While (! Terminated && Clientsocket-> Connected)
{// omitted some code
Stream = New TwinsocketStream (Clientsocket, 60000);
IF (PStream-> Waitfordata (60000))
IF PStream-> Read (Buffer, 10) == 0)
Clientsocket-> close ();
The connection is only closed when the data is received is 0.
2. In the ClientExecute function of TdissvrCltthread, the waiting connection is performed and read data. And send data.
There are three misunderstandings above:
1. The above multi-thread is not generally thought, and the client will create a thread every time you send a data, then Terminate this thread. Instead, after the end of ClientExecute, the thread is not over, hanging there, has a new connection, and continues to run ClientExecute. Only when there is a new connection, the previous thread is still busy, and now builds a thread. Anyway, keep the number of threads. This is really good. 2. I used the code while above (...)
Discover, the above, if you run a batch, you will always run this thread, although there is a new thread. But in fact, the port can't grab. As a result, the client is unable to be a common thing (perhaps only my word "). Later, I did no matter how, each connection, after receiving the data, turn off the connection (of course, it is useless to keep the connection). Of course, it also removes the while, running from ClientExecute every time. The result of this is a multi-service thread and a single almost: serversocket-> ActiveThreads can be seen.
3. PStream-> Waitfordata (60000) seems to have no effect, often when the data is 0 is 0, that is, often clientsocket-> close (); and waste time. To the 9CBS BCB sector, find some examples of stthreadblocking. I found a sample for two Waitfordata, I also tried it, it is really effective. This rarely received 0 bytes.
As soon as, in this case data is sent, I just started watching the properties of ClientSocket in TSERVERCLIENTTHREAD. I thought I can use it directly to send data! Later, I found some points. TSERVERCLIENTTHREAD, when there is a connection coming in, take the initiative to get data (should be right!). The specific technical details are not clear. Ha ha. I still use the thread used in front to send data, and I don't have to change things.
Of course, it also considers the problem of multithreading access conflicts:
The N service thread (although most of the time only one service thread, but it is possible). The function of address configuration information is a critical resource problem, with TcriticalSection. There is a variable that determines whether the data distributed in the whole area can use the volatile keyword.
The N service thread passes the parameters to send the thread, with TEVENT, so that the thread will not send the thread yet to save the data, the service thread will remove the resources.
The current plan looks perfect, isn't it?
E. Use VC to do solutions.
CSocket is now use VC to do network commonly used classes, and it has been used, and it has been used for a long time. I have forgotten how to use it. Still use it, you can forward something. Although there are a lot of problems. Just do it, I found that in the case of the structure, like ASIString above. The error will appear when the DELETE structure is. With Char Strid [6], then the error did nothing. Doubt is CString, Ansistring will appear in the structure (also appeared in BCB). So, when I said inexplicable mistakes, I published an opinion on the problem of ANSISTRING in the structure and was hurt. Come back and hurry, really, simply do one, there is no problem. depressed! Csocket is not blocked, but also seems to have several files, there is not much place. It is still written by API. So, two thread functions (it should be almost). A Svrsocketthread, CLTSocketthread.
It should be SvrsocketThread. Often seen Svrthread is
While (True)
{
IF (bwanttoExit)
EXIT;
SocketAccept ();
Do Something ... ..
}
Later, I saw this way of writing.
IF (bwanttexit)
EXIT;
SocketAccept ();
Afxbeginthread (...);
DOSMETHING ();
EXITTHREAD;
There is also a feeling that I am finally found, don't say anything, it should be much better after it is. Perhaps it is a programmer's nature, and it is cool to see the code. The latter code is also used in the back of DOSMETHING. Maybe I don't have to say, the first way of writing is the writing of a single-threaded service. Second, there is no doubt that it is a multi-thread. Perhaps, I am really me is too lonely. Such a good code is now discovered, maybe, I have seen it, but I didn't pay attention. For event triggers in the VC, you can use the API, such as STEVENT, CREATEEVENT, WAITFORSINGLEOBJECT, WAITFormultiobject.
This program made with VC is also completed. There are still a few questions: Temporarily, in order to check.
1. Socket is restricted to the problem. After the first binding a port, I want to resize this socket, although CloseSocket, WSACLEANUP is also called. But the additional port cannot be bound. Now that you want to bind another port, turn the port close and build one with the socket function. Is it a case to re-build a socket to bind. Nored Other Clear Socket functions. In addition, if the binding port is occupied when renovating a socket, then it will never come back, even if it is re-given an empty port.
2. In ListView, a CEDIT has been built, and the TabStop property is set. ListView has showSelectalways, but when using CEDIT, the place selected by ListView is always grunge, never want me to overload CListCtrl for this small problem Bar.
3. There will be a "ready" status display in the lower left corner of the status bar, and this string can also be found in the resource. Now I want to set up dynamic settings in the program, but I don't know how to do it. Now I can add a PANE, "Ready" is not PANE. F. Finally, the climax is part, this is what today is doing: Provide multi-service ports, and can dynamically apply for a service service. And the above description is as follows:
1. Use the service to make a good code about the code prepared by the service program, it is completely written. Of course, the most complete or that includes a HelloWorld program that includes installation, start, control, and close, etc. Today I found that there is a service exe in the ATL COM wizard, and the ccommodule is used as the base class. This is not very good! This is much simple. The code registration part is divided into Server and Service, hey, failure, can't distinguish between their difference. Register. It seems that Server is not registered inside the control panel component, and service is there. I want to know how DLL's service is done, someone tells me? I think there should be servicemain exported, but I found a DLL (system), use Depends, only one function is exported, but can also control it in the component, don't you have a handler?
2. The thread structure is this: There is a service thread that deals with the application to open the port (of course, the corresponding port is administered via this service thread. Other threads manage a distribution port separately.
3. More than one layer above, it seems not enough to use INI to make a profile. Here is the use of XML as a configuration file, it is also learning MSXml.dll usage. So, a special class of XML was born again, and the CXMLFILE was described.
4. Consider writing the logs. Both, system logs and business logs, system logs naturally record the log of the control panel, the business log, can be done by another service program, can consider the counterfeit service program - interface But hidden the interface, for the form, you can send the log via SendMessage, PostMessage. The content of the content is probably possible, but it can not be recorded in real time (may be?). I don't know if there is a way to send a message by knowing the process ID. Consider using additional procedures to do logs, one is learning, the second is to directly record the log to the hard disk, the operation of the input and output affects performance, and the business log is too much. Of course, this has been taken into account in the previous stages, not that each record is saved to the file, but will write a file when reaching a certain size.
5. The service is quite small, and the default generated project does not support most of the MFC, huh, huh. CCOMMODULE should be an MFC! SDK's things are too small, it is really not easy. For example, CString :: Format, Carray These should be used, you can make yourself, you can feel annoying. I have to join the header file. However, most of it, use or SDK things, at least cxmlfile is.
July 11, 2004
The re-bound port is already, it is also almost the same, to make a service, still not finished, the relatively failed, maybe someone is right, learn the high-level language make people become impetuous. If someone needs, I can send VC source code. The way to say that new threads is started every time, there is also a shortcoming, that is, when starting a new thread, it will inevitably consume a more resources, and then I will see the network programming of the completion port, it should be in Windows network programming. One of the best ways. Below
Understanding I / O Completion Port Nonocast (original) http://community.9cbs.net/expert/topic/3056/3056877.xml?temp=.3150751