For some time I've been promising to update the socket server articles to use the latest version of my code. Today I finally updated the code for the first article. I'm going to update the article itself soon, but in the meantime I'm posting the new code here.
[NOTE: This code leaks when adjusted to build with Visual Studio 2005. This seems to be due to a bug in VS2005's STL. See here for a workaround. I expect to post a fix for this once I've found time to convert the code to build with the new compiler and then tracked down the leak. If anyone has already done this then a comment telling me what's wrong would be appreciated.]
What's new?
1) You can now compile the code with VC6 without a Platform SDK installed. To do this, edit NoPlatformSDK.h and uncomment the #define.
2) The sockets now share critical sections. The previous code suggested either allocating a critical section per socket, or sharing one section between all sockets, at the time I mentioned that this was less than ideal and that you'd probably want to do it differently in a production system. Now I'm including a shared critical section system that uses a hash to spread the contention across a pool of critical sections.
3) Servers can now share the IO thread pool. You can now create multiple servers and have them share a single pool of IO threads. This makes creating servers that listen on multiple ports much less resource intensive.
4) The server can now initiate outgoing connections as well as accept incomming connections.
5) All examples can now build with VS.Net 2003 as well as VS.Net 2002 and VC 6. All examples come with project files for all three build systems.
6) You can now have multiple user data "slots" per socket. This makes it easier to layer services on top of the server and still allow the client to add their own user data to each socket if they want.
7) Each example ships with a test harness and config file to test the server as part of the build process, if required. Notice the difference in performance between the debug and release versions...
Thanks a lot.
Your code is very help to me.
Thanx for your code, very nice work. I have tested it for quite a long time, some problems unsolved that may be a configure inaccuracy or some performance bottleneck somewhere, the issue is: I always confront intensively large ratio of denied connection from client side, say, a test of 500 threads, 40% ~ 90% of connections will be refuesed, although I may trust your architecture as optimized for large-scale network server, but such high ratio of failed connection may suggest its inability to handle high-load connections. I have tried to change socks in pool and way of threadpool, but no noticable improvement. I hope you could possibly reply me on this problem, and if convinient, give suggestions on high-load server. Thanks!
Posted by: mark zimmern at September 28, 2003 09:20 AMHave you tried running the test from more than one client machine? It may be a problem with your client side code, or it may be a problem with the client side using up all available ports if it's opening and closing connections quickly (leaving ports in TIME_WAIT state, etc). What does netstat show on the client and/or server? Are you running the release version of the code? The debug version is considerably slower due to the locking done around the debug output (this makes a huge difference to the performance of the app).
Posted by: Len at September 28, 2003 10:24 AMThanks for reply, yes I have a carefully arranged test so all possible situations, include local test and between workstations, and the client tools are vary also. The result is similar, though we might go around with less chan se of error by turning down the numbers in:
300
10
1000
but anyway the disability to connect to remote socket did happen in most tests, combined by an other error that indicate a failure to transport any message. I havent found a solution to it yet.
An other problem is the memory issue, it seems quite interesting, the echo server and packet server are using extremly little memory that is comparable to virus, among 200k-400k, when under large connection pressure, and it decrease memory usage as time goes by, very strange. On the other hand, the large packet server with thread pool eats more than 300M memory when it starts to take incoming connections, abnormal, might be leaks somewhere.
Posted by: mark zimmern at September 28, 2003 01:40 PMsorry, 300,100,1000 are actually settings, xml tag are filted after post. I forgot to mention the block on CSocketServer::OnConnectionReset during one test method in which I send request to 1000 local http proxy servers to connect to the test server running jetbyte socksvr, repeatly, to simulate real-world server task, and I found, very soon after several sessions, it will hang up in onConnectionReset, the version I used is the updated echo server. Hope u could give useful advise, greets!
Posted by: mark zimmern at September 28, 2003 02:04 PMWhat does your client machine's netstat command say at the point where you fail to connect? I expect you're running out of ports and ending up with lots of old connections in time_wait. This is normal - you dont expect to run 10000s of short lived connections on the client side. As I suggested, run with multiple clients using fewer connections per client and see if you can go above the limit for a single client. If so then I'd suggest the problem is on the client end and not the server end.
The memory issue is as expected. Take a look at the code... The echo server uses 1024 byte buffers and writes the response back to the client using the same buffer that it uses to do the read (as far as I can remember). Memory will decrease as we only pool a certain number of buffers, so when the connections die the buffers are released. So it will only use 1024 x number of active connections for buffers. The large packet echo server uses 1024 byte read buffers and 65536 byte message buffers (between socket server and business logic thread pool), it also echoes the messages back in small chunks (666 bytes) so will naturally create many more buffers than the other servers. This is by design, read the associated articles for the reasoning.
If you need masses of incomming client connections then it's probably worth specifying the 'use zero byte reads' option as this will reduce the amount of 'non paged pool' that is used by the server. Again, read the articles and comments for details.
Posted by: Len at September 29, 2003 11:28 AMthanx for your answer.
Posted by: mark zimmern at September 30, 2003 06:43 AMThanx for your greate code, it was very useful to me about basic of IOCP architecture.
but, i have some request..if you will.
I wondering belongs -the Test.dsw code include whole project..
-SocketServerTest.exe
-SimpleProtocolServerTest.dll
-SocketServerTestInterfaces.dll
because, As i made custom server use your library,I don't have especially testing Tool.
so, Could you show me some test library code or let me know how do you made the TestingApp.
For example,
Testapp's architecutre?
The sequence?
the way..
got it? My english is very poor. sorry... :)
thankx.
Thanx for your greate code, it was very useful to me about basic of IOCP architecture.
but, i have some request..if you will.
I wondering belongs -the Test.dsw code include whole project..
-SocketServerTest.exe
-SimpleProtocolServerTest.dll
-SocketServerTestInterfaces.dll
because, As i made custom server use your library,I don't have especially testing Tool.
so, Could you show me some test library code or let me know how do you made the TestingApp.
For example,
Testapp's architecutre?
The sequence?
the way..
got it? My english is very poor. sorry... :)
thanx.
The test harness is written in C#, it's documented in this article, source is supplied: http://www.jetbyte.com/portfolio-showarticle.asp?articleId=46&catId=4&subcatId=11
Your english is far better than my Japanese (guessing from your .jp email address) :)
Posted by: Len at October 3, 2003 10:51 AM^^
thanx, very quick..!!! :)
and also, you should erase i wrote comment in duplicate.
ps.your home page is very smart~!
i like your style. ^^
Done.
Posted by: Len at October 3, 2003 12:27 PMi have question one more time..
in XML
i can't type ^,^ so, replaced "[","]" ok?
[Conversations]10[/Conversations]
why do you have added the parameter, if i had set up
[Multiple]>true[/Multiple]
then, do i need set up
[Conversations]10[/Conversations]
how about it, the code have modified to
[Conversations]1[/Conversations]
and, in plug-in dll , added more message
alike
messages = new IMessageExchange[100];
messages[0] = new MessageExchange("USER test\r\n");
messages[1] = new MessageExchange("PASS test\r\n");
messages[2] = new MessageExchange("STAT\r\n");
messages[3] = new MessageExchange("RETR 1\r\n");
messages[4] = new MessageExchange("RETR 2\r\n");
messages[5] = new MessageExchange("RETR 3\r\n");
messages[6] = new MessageExchange("QUIT\r\n");
.
.
.
.
.
messages[99] = new MessageExchange("QUIT\r\n");
it was almost nothing to do with server testingApp.
but, i just wonder, is it right? or not.
The number of conversations is the number of times the entire test is run on the connection. So the test harness will connect to the server, it will then loop for the number of conversations and each time through the loop it will send all the messages that the MessageExchange object contains.
The multiple message flag is used to decide if the server will send multiple messages in one send(). This forces your server to deal correctly with multiple messages arriving in a single read call... The fragments flag determines if the test will send bits of messages and force your server to deal with a single read not returning a whole message.
Posted by: Len at October 8, 2003 01:15 PMoh!!!!!
you mean, you wanna test just connection per thread... after all, one thread is almost same that seperated computer or client.
is correct? i understood,your testapp was just Send/Reply Testing.. i miss it.. right?
is Conversation parameter for just connection testing?
What & how should the server do, while the client pc is shutdown or turned off.
Posted by: Jackie at October 9, 2003 07:39 AMThe server may or may not realise that the connection to the client has been terminated; read up on how TCP/IP works. If the client or server closes the connection cleanly then the server will know straight away. If there's some sort of problem (network cable pulled out, router failure, client pc crashes) then the server will only discover it when it next tries to send a packet to the client. If you want to know as soon as possible then you need to either use the TCP/IP keep alive stuff or implement your own application level keep alive protocol.
Posted by: Len at October 9, 2003 07:57 AMRe the test harness:
I was wrong with my description the last time around.
The test runs with multiple threads. Each thread runs a test. Each test simulates multiple connect/disconnects each of these is a 'conversation'. Within a conversation the messages in a message exchange are sent/recieved.
Posted by: Len at October 9, 2003 08:03 AMI wanna ask question related to following constructor function...
CSocketServer server(
lockFactory,
pool,
"+OK POP3 server ready\r\n",
INADDR_ANY, // address to listen on
5001, // port to listen on
10, // max number of sockets to keep in the pool
10, // max number of buffers to keep in the pool
MAX_RECV_BUFF); // buffer size
what's the limit?
socket number, buffers, buffer size?
I knew, it's depend on myServer resource.
but, i wanna know what things have something do to with the parameters.
Could you explain ... concern with client(user),
for example,
i waana service for 1000 user
max packet size is 1024*10 byte = 10Kbyte
then how many buffers i need? set the case, hardward(server) resource support enough.
The numbers for the socket and buffer pools just relate to how many socket and buffer structures are kept in memory ready for use. If you need 1000 buffers then 1000 will be allocated, if you set the buffer pool size to 100 then when all 1000 buffers are no longer required you will still have 100 in the pool ready for immediate use. It's a performance optimisation...
Posted by: Len at October 10, 2003 08:49 AMi having implement own chatserver,
i try modify your SimpleProtocolServer to simplechatserver.
but, On broadcast active user,
Can i use
SocketList m_activeList;
?
but, this is protected member,
then Do i have to create some method for get m_activeList.
if have idea, please explain..
ps.
hey len, didn't you sleep?
what time are there?
Sorry to disturb you again but i like to clear one problem in my try...
i found your document in codeproject.com
there are some hint about hadling connections.
//////////////////////////////////////////////
Maintaining per-connection state
The final thing that our server may need to do is associate some internal server state with a particular socket connection, the Socket class makes this particularly easy as it provides the following member functions:
void *GetUserPtr() const;
void SetUserPtr(void *pData);
unsigned long GetUserData() const;
void SetUserData(unsigned long data);
/////////////////////////////////////////////
so, to make chatserver-broadcast function- should i use above function? if so, Do i need other criticalsection for connection manage?
plz give me some advise.
thanks.
after all,
in a word, where do i get connected user list?
thanks. again. :)
sincerly yours.
Posted by: devkim at October 10, 2003 07:59 PMYes, use the Get and Set UserData functions. You need to make sure you tell the server how much space you need, you pass a user data slots parameter to the server constructor. You probably dont need to lock around access to the user data slots as normally only one thread will be doing this at a time...
Re the user list. I'd personally implement my own application level user list. I wouldnt try and use the active socket list that the server maintains.
Posted by: Len at October 10, 2003 08:02 PM--) Re the user list. I'd personally implement my own application level user list. I wouldnt try and use the active socket list that the server maintains.
the meanning.. is it my own job?
to get the userlist, Do I have to own application level user list for broadcasting message? right?
sync.(criticalsection for userlist) as well?
my english is so poor, so it's difficult to know what you waana explain..
sorry..
Posted by: devkim at October 10, 2003 08:57 PMYes. You need to write the user list and manage it. You will need to use a critical section to sync it.
Your english is still better than my Japanese, don't worry about it :)
Posted by: Len at October 10, 2003 09:59 PMHello Len
Great code.
Have you compiled and posted the COM component yet? Also how do you code a client to talk to the server.
Regards
JB!
Posted by: Joseph Brown at October 14, 2003 04:41 AMJoseph
I haven't updated the COM component; truth is, we don't use it for much so it doesnt get much attention. It's on the list though.
Quite often we use the server framework for clients as well - hence the outbound connection support. It depends on what the client is for and which platforms it supports. Other times we use something similar to the MFC client that we put together for the SSL article.
Posted by: Len at October 14, 2003 08:07 AMhi.there.
it's me agian. didn't you miss me? ^^
I modified your code for chatting server.
in Sample simpleprotocolserver,
i have chaged the code,
void CSocketServer::ProcessCommand(
Socket *pSocket,
const CIOBuffer *pBuffer) const
{
.....
....
...
if (ok)
{
// We understand, but we aren't really a POP3 server...
std::string response("-ERR sorry, we understand \"" + echoCommand + "\", but, we're just a fake POP3 server...\r\n");
{
JetByteTools::Win32::CCriticalSection::Owner lock(m_listManipulationSection);
Socket *pSocket = m_activeList.Head();
while (pSocket)
{
Socket *pNext = SocketList::Next(pSocket);
pSocket->Write(response.c_str(), response.length());
//pSocket->AbortiveClose();
pSocket = pNext;
}
}
...
...
...
}
i also have chaged privte member value
"m_listManipulationSection"
"m_activeList"
to public member
any problem?
I didnt follow your suggestion. but, it was not problem, yet.
Can i use this way, for chatting server?
thanks.always.
Posted by: devkim at October 20, 2003 09:59 AM> any problem?
You're coupling your code to the framework in a way that wasn't intended. It'll probably work. I'd probably do it differently.
hi,there.
i have made newproject using Devstudio appwizard.
project-win32application (vc6.0)
and, your simpleprotocol souce file move to DSW.
and having compile.
but, there are many many linking error occur.
- LIBCD.lib crashed...
so, i ignore LIBCD.lib in my project option, but,
another error occur.
-LNK2001: unresolved external symbol _errno
so how can i resolve the problem?
and there are some lint option, but, i don't konw what it does.
thanks.
Sounds like your compiler options in the new project dont match the library options. You need to make sure that the new project uses the multi-threaded static library build, not the dll or single threaded build.
Posted by: Len at October 24, 2003 08:34 AMgreat!!
thanks. anyway, it's too difficult proejct setting like this..
I often encounted such problem..when i linked C library and anything else.
thanks.
Posted by: devkim at October 24, 2003 10:06 AMI never seem to create new projects these days, I copy a dsp file, open it in notepad, do a search and replace for the 'blah' of 'blah.dsp' bits and then open it in VC and adjust the files. This way all the settings stay the same ...
Posted by: Len at October 24, 2003 12:50 PMone more...
you seem to be forget my another question.
about "lint option"..
could you explain for me?
The lint options file and lint comments are because I use Gimple Lint (http://www.gimpel.com/) which is like running your compiler with the warning level set to 11.
I don't know if I like the fact that I contaminate the source with warts that suppress warning messages for things that I want to be warned about but sometimes like to turn off because I know that the warning is being too cautious... It works, but I think I'll end up moving away from the //lint comments etc and use external suppression files.
Posted by: Len at October 24, 2003 04:28 PMHi Len,
Thanks so much for sharing your code. Out of all the free packages I have seen, yours is by far the most well designed. Unfortunately, when just testing the code on my laptop I can not ge the echo server to respond reliably. I am assuming that this is something about my particular setup, but I just wanted to let you know.
I am running an IBM Thinkpad P3 500 with Win2k Pro, MSVC++ .NET (2000) and the loopback adapter. I was just running the compiled version and connecting with telnet.
Thanks again for sharing your hard work with all of us.
Cheers,
Adeh
Is this the C++ echo server you're talking about or the COM one? Try changing the ports? I think 5000 is used for something on some boxes. Try doing the complete build and letting the test harness run? If it's the packet echo server remember that you have to send the packet length first (see article).
I know it's not in any way helpful to you but 'it works for me and the test harness thrashes it pretty hard', I'm surprised you're having problems with it...
Posted by: Len at November 5, 2003 08:08 AMyour code is very good
Posted by: aku at January 15, 2004 04:35 PMi want setup business server support more than 10000 client from diffent workstation on internet.
your code is usefull to me.
Aku - Thanks. Do you mean 10000 simultaneous client connections? If so you probably want to set the 'post zero byte reads' flag when constructing your server. This reduces the amount of "non-paged pool" that the server uses when it's running.
Posted by: Len at January 15, 2004 05:07 PMthanks.
i setup a project use MFC APPWizard. than add your
Win32Tools to the project, but report errors
Linking...
nafxcw.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) already defined in LIBCMT.lib(new.obj)
nafxcw.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) already defined in libcpmt.lib(delop.obj)
../../Bin/OutlookBar.exe : fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.
how to resolve the problem?
Posted by: aku at January 16, 2004 02:31 AMmy project Use MFC in a static library.
Posted by: aku at January 16, 2004 02:47 AMLooks like you're not linking with the multi-threaded libraries. The socket server stuff links with the multi-threaded versions of the runtime libs so your main project also needs to link with these.
Posted by: Len at January 16, 2004 06:39 AMThe socket server stuff links with the multi-threaded versions of the runtime libs so your main project also needs to link with these.
Yes, main project link with the multi-threaded versions of the runtime libs , still report that.
Posted by: aku at January 16, 2004 04:25 PMHi Len!
I'm sorry for this real quick q. I already sent you an E-Mail about it. So. I based my project on the article "Handling multiple pending socket read and write operations" and the code there "..server6". Now I see you have an update. but all the projects in SocketsServer.zip look a lot different from what is in the article. For example the thread pool instead of like 10 params has just one :D. On the other hand I see bits of the code in socketserver.cpp that handle the sequence. So the question is which project in the socketservers.zip is the one that takes care of the "Handling multiple pending socket read and write operations"? Can you just quickly give me an idea where at least to read about this package?
hi len, how are u?
i resovled problem above, your simple protocol is too simple, i must write a protocol ,
^_^, that is very simple to me. thanks you very much.
happy new year, have a good time.
Max, the code has been updated, the articles haven't. Therefore you should look at the code that comes with the articles if you want to understand the code and then compare to the latest code if you want to understand the changes and fixes. I haven't had a chance to update the articles yet.
Posted by: Len at January 24, 2004 10:36 PMhi, len.
when did you update your lib?
you mean, since I ask some problem above, you did?
The code hasnt been updated since I originally posted this entry.
Posted by: Len at January 28, 2004 08:07 AMHi, Len! Thanks. It's just what I thought. :D Ok.
So I know the code in articles. Now I've got to dive in and compare it to new one.
Will you update articles, though? I'm not insisting, but people may ask too, no?
And still which project for the "multiple read/writes"?
Posted by: Max at January 28, 2004 03:50 PMThe code's currently being changed again to support some new stuff that a client wants. Once that's been done, if we get some spare time, we may update the articles to bring them in line with the latest code...
Code for the multiple read/write is attached to the later entry: http://www.lenholgate.com/archives/000088.html
Posted by: Len at January 28, 2004 04:29 PMRe: 4) The server can now initiate outgoing connections as well as accept incomming connections.
do you have solid code examples of this in action?
Posted by: T S at July 23, 2004 11:34 PMT S
None of the sample servers in the zip file initiate outgoing connections. We use this functionality in some of the code we've written for clients using this framework. You just need to call Connect() on the server and it gives you a socket which will then operate exactly the same as if you'd had someone connect to you as a server...
Len
Posted by: Len at July 24, 2004 06:46 AMTnanks a lot for ur great work.I meet a problem:
When my server is starting up,There are hundreds of connections comes.All the connections are connected.And I have to send back lots of data to the client.And the data I send to the client can't be all writen:
"CSocketServer::WriteCompleted - Socket write where not all data was written"
What should I do?
Interesting.
I've never managed to get that to happen, though I've tried quite hard with our tests. If you'd like to email me with more details I'll try and help.
Posted by: Len Holgate at September 6, 2004 09:45 AMHello:
It seems to be my problem.but I have another question:
void CSocketServer::Write(
Socket *pSocket,
CIOBuffer *pBuffer) seemed to be called in iopool.
It remove the FIRST Buffer from the queue and call WSASend,But before WSASend,the system switch thread to another io thread ,and it remove the NEXT FIRST Buffer from the queue,and send to the client.then when the first thread is running,send the buffer,the queue is out order?
Wintrader,
Which sample are you using? Have you read the articles that go with the code on www.codeproject.com? If you're using sequence numbers, when you call Write() a number is allocated and the write request is posted to the queue to be actioned on an IO thread. The IO thread will make sure that the writes are issued in the order that they were posted. You cant have multiple threads calling Write() on the same socket at one time and expect to maintain any form of ordering unless you do so yourself.
Posted by: Len at September 8, 2004 06:20 AMI first use ThreadPoolLargePacketEchoServer sample.Since there seem to be a lot of problem on my application using this way,I have disable the business logical thread pool now.
ThreadPoolLargePacketEchoServer is the most complex sample and, to be honest, we hardly ever need that complexity. It's useful if you have packets that are variable size and where most are small but some are huge. If you're using the business logic thread pool samples then you need to make sure that sequence numbers are turned on.
Use the simplest architecture that you can get away with. You only need the business logic thread pools if you are doing blocking calls; such as db access. Even then you can get away without using the business logic pool if you accept that your performance wont be as good.
I do consulting work, if you're interested, drop me a mail.
Posted by: Len at September 9, 2004 12:23 PMNow It seems that every thing is ok!It has been running for 2 days!And the system performance is better than the original one.My system needn't create threads for the incoming connections but using the io thread created already.This week I will continue to test it.Thank a lot!I'm good at finance related programming such as stock or futures analyse or data provide.My email is:
wintrader@163.com,may I email to info@jetbyte.com to contact with you?Thanks a lot again.
Cool.
Posted by: Len at September 12, 2004 11:16 AMI'm new to socket programming and programming at all. I’m browsing through your code and trying to figure it out. What I actually want to do is to send distinct messages to clients depending on some program logic. I suppose that I need some kind of array of Socket pointers, don’t I? What is the recommended approach regarding threading etc.?
Thanks!
You might want to go and read the articles I've written on www.codeproject.com - though they're hardly aimed at beginners. There are probably introductory socket articles on there which might help you.
Posted by: Len at September 14, 2004 01:54 PMI like your code very much, but i can't understand meaning of constructions like this:
class COpaqueUserData
{
void *GetUserPtr() const
{
return InterlockedExchangePointer(&(const_cast(m_pUserData)), m_pUserData);
}
because it is possible to lose data here, construction "return m_pUserData;" is enough because simple reads and writes to properly-aligned 32-bit variables are atomic. In codeproject version you use InterlockedExchange in CSocketServer::Shutdown() also.
Posted by: alex at February 14, 2005 07:49 AMThe InterlockedExchangePointer things are left over from when I was having some issues locating a race condition when changing a value - I couldn't find any references that guarenteed that 32-bit accesses were atomic so I put them in to make sure. The problem turned out to be something else and the code never got changed back, it's on the list of things to do.
Posted by: Len at February 22, 2005 12:55 PMThis framework has been tremendously helpful and informative to me. Just following your code has taught me tons about the practicalities of IOCP programming. Thanks for your work.
Would you please confirm that the latest public release of your work is dated June 13, 2003 and can be found on your blog at http://www.lenholgate.com/archives/000082.html[^]. If it is, then as a suggestion, you might want to update the article itself (in the "Revision History" section) to mention that the most current public update should be downloaded from your blog and not from CodeProject (or from JetByte??), so that the unwary do not get older code.
Would you also please talk about the few bugs mentioned at your site after June 13, 2003. For example, at http://www.lenholgate.com/archives/000270.html[^] (dated February 29, 2004, i.e., after above-noted public release), entitled "Why I started thinking about obvious complexity", you mentioned that there is a "bug in the recent public release" without giving too much of a clue into the nature of the bug. Have fixes for these been incorporated into the public release? Likewise, have improvements been incorporated, like those mentioned at http://www.lenholgate.com/archives/000305.html[^], entitled "Easy performance improvement for the socket server code" dated May 17, 2004.
Finally (and I apologize for asking for so much), have you reached any conclusions on your revelations and new insights on the AcceptEx server, as mentioned at http://www.lenholgate.com/archives/000268.html[^], entitled "Implementing the new AcceptEx server" dated February 27, 2004?
Best regards,
Mike
Mike,
I saw this comment on code project a while ago and I've been meaning to reply but, well, I've been skiing...
I'm back in the UK now and will be spending a bit more time on work related issues and will respond to your questions more fully in the next few days.
Mike
Yes the latest code is and will be on the blog from now on. Good idea re updating the revision history. I've done the www.jetbyte.com pages and will get the codeproject pages done as soon as I can.
I can't remember if the bug was fixed and new code uploaded. Sorry. It's fairly obvious as it's a huge memory leak...
The performance improvements have been included in our version of the code but they haven't made it in to the public release yet.
We still haven't had a need for AcceptEx in production apart from the bluetooth server. The BT server doesn't include support for "accept and read" accepts so we still havent needed to deal with the denial of service attack that's possible if you do support "accept and read". So, in answer, using acceptEx to remove the need for a thread per port is a good thing and works well but we haven't come up with a more robust solution to the accept and read problem.
Posted by: Len at May 4, 2005 04:42 AMSorry but I cant understand your architecture, I cant figure it out how to transmit large amout of bytes
Posted by: Fer at May 4, 2005 12:52 PMHave you read the articles on code project?
http://www.codeproject.com/internet/jbsocketserver1.asp
Posted by: Len at May 4, 2005 01:00 PMplease help me ....
its urgent .
please send me the code for multiclient chatting application using socket programming implemented in C which has following features..
1.REGISTRATION
2.AUTHENTICATION(LOGIN PASSWORD)
ITS A BIG CHALLENGING TASK FOR U....
WAITING FOR UR REPLY
Send me an email with your requirements and I'll sort out a quotation for the work. When the agreed fee arrives in my bank account we'll begin the work for you.
Posted by: Len at June 1, 2005 02:52 PMHI,Len
Where is the latest socket server version?
thanks
burns
Posted by: burns at June 3, 2005 04:07 PMThis is it.
Posted by: Len at June 3, 2005 04:55 PMthis is a great job!
can you code a udp socket server?!
We have a UDP server based on an older version of the code. It's avaialble here.
Posted by: Len at June 10, 2005 09:19 AMThank you very much.
you are so kind.
Hi Len,
what is your opinion about the best solution of following scenario?
I have to write the server application which
works with two TCP services (two separate ports).
The both services have to talk with only one instance of RS232 (serial port COM1), sharing it.
Haw to resolve it with aid of Your TCP Server Library?
I'm new by this stuff, please to help me to find the good way to solve it.
Norbert
Norbert
Create two server objects, one for each port. Pass each server object an object or interface to an object that talks to the serial port. Put whatever locking is appropriate in the serial port object. Access the serial port object from the server objects when data comes in.
We can quote for providing a design and or implementation if you'd like.
Posted by: Len at July 13, 2005 01:09 PMHi, Len.
Would you like to tell me why to use '47' to initialize the 'CSharedCriticalSection'? like this sentence 'CSharedCriticalSection lockFactory(47);', thank you.
The hash algorithm used works better if the number of locks is a prime number, 47's prime and for my sample servers it's not too big and not too small ;)
There's an instrumented version of the multiple lock manager
CInstrumentedSharedCriticalSectionif you replace the usual lock manager with this one then you'll get some 'useful' information out to help you tune the number of locks that are appropriate. Posted by: Len at July 26, 2005 08:11 AM
got it!
thank you very much.
No problem. What are you using the framework for?
Posted by: Len at July 26, 2005 01:12 PM:)
just a simple protocol server based on tcp server.
Hi, len
Where can I find the update of ThreadPoolLargePacketEchoServer which mentioned in
http://www.jetbyte.com/portfolio-showarticle.asp?articleId=44&catId=1&subcatId=2
Did you make it use the new updates, such as
The sockets now share critical sections, Servers can now share the IO thread pool?
I didn't update that one; it's left as an "exercise for the reader" ;) It should be fairly straight forward to take one of the updated examples and adjust it.
Posted by: Len at August 12, 2005 08:19 AMwhat a surprise quick answer!
Thanks, I will try to exercise then...
Posted by: Sean at August 12, 2005 08:34 AMHi Len,
i really like your approach regarding pool of critical sections. is there any place on the web where one can read a little bit more about this technique? is this a usuall synchronization technique when writting high performance servers? is there any book or a web link that explains tips and tricks regarding server side programming (apart from Richter's book)? i have to admit that i learned a lot about nice ood and coding techniques while browsing your blogs. i hope you keep the good work in the future. thanks.
Posted by: alek at November 12, 2005 08:51 PM... and one more thing .... how do you figure out how many critical sections to crate in advance. is it necessary to tune this value if the number of known concurent clients changes? thanks.
Posted by: alek at November 12, 2005 09:05 PMAlek
Re the resource pooling stuff; I haven't seen this written about anywhere but it's fairly simple stuff. I've no idea if it's the usual practice, but it does allow you to trade resources for performance. Also, due to the fact that the critical section pool is accessed via an interface and not a concrete class you can replace it with a different style of factory relatively easily; I've done this with an instrumented lock factory that can report the distribution of the locks (ie how many locks are shared) and also to allow switching to no sharing by simply always returning a unique lock.
I've not actually needed to tune the lock numbers that often. Usually the default values work fine; as always you'll need to profile your server and see what works best. The deadlock detection tool that I've been working on can also show lock contention counts, which is useful for this kind of tuning but, of course, simply measuring the contention can change it...
Jeff Darcy has a nice piece on high performance server design here: http://pl.atyp.us/content/tech/servers.html
Posted by: Len at November 13, 2005 03:44 PMHi,
if post multiple WSASend() and a WSASend() only send partial buffer,not the whole buffer,How can I do with it?
thanks much for your code!
Posted by: Sunrong at December 10, 2005 01:08 PMIf a WSASend() fails and only sends some of the buffer then you could try reissuing another send with the remaining data, of course this is more complex if you have alreade posted other WSASends(). What you can do really depends on the application protocol that you're using. There is no simple solution except trying not to get into that situation by actively limiting the number of connections that you accept and the amount of concurrent overlapped operations you start so that you avoid the resource limitations that can lead to the problem in the first place. See the stuff I wrote here http://www.lenholgate.com/archives/000570.html about the resource limits and how to avoid them. The licensed version of the code now includes code to allow easy limiting of connections...
Posted by: Len at December 12, 2005 02:24 PMThanks!!!
Posted by: Sunrong at December 14, 2005 01:28 PMHi Len,
I would have a question regarding exception handling ... I was thinking to reuse your framework in an ATL (vc 6.0) based project, but I'm not sure how COM exception handling would fit in this story ... Would you have some suggestions?
best regards.
Posted by: Steve at January 28, 2006 07:31 AMSteve
The way you need to deal with exceptions doesn't change if you use ATL and the wrappers that generate exceptions from failed COM HRESULTs. You should NEVER allow your exceptions to propogate out of your derived class's event handler functions and into the framework.
Posted by: Len at February 5, 2006 04:56 PMsir,
i have written a vc++ program using winsock control to send messages to vb client program.
i have written the server code in such a way that it can accept single connection request only
if i stoped client program means i have to rerun both server and client program
how to modify the server program so that it can accept more than one connection request at the same port
Read the docs for the winsock control?
Posted by: Len at March 9, 2007 05:25 AMHi Len,
I have written a c++ test tool to test your SimpleSocketProtocol2 server that connects to the server and waits for data to arrive in from the server.
Basically, what happens is that the server keeps sending data to the client. The client consumes the data normally. However, when a disconnection happens (either a server or a client disconnection), last reported message received by client is different from last reported message sent to client by server. Say, server says, i sent you message 20, however client logs message 15 as his last message.
What could have gone wrong here?
Any clues?
Posted by: Firas at June 5, 2007 09:22 AMIf you have a protocol between the client and server that allows the client to acknowledge safe reciept of a packet then you will know which packets arrived safely from that... If not then data will likely be in transit in the tcp stack of the server and client and this could be lost when the disconnect occurs.
Without an explicit protocol between client and server for flow control you can flood a client with a faster server/link and you'll end up buffering data in places that are out of your control (like the tcp stack)... This isn't such a good idea ;)
Posted by: Len at June 5, 2007 09:50 AMThanks for the response...
It is exactly as I expected.
Well... could a slower sending server (one that is forced to lower its speed manually) kinda lessen the effect of such a behavior? Is there an ideal solution for this in case there is not any explicit protocol between the client and the server?
If you wait until you get a write completion from the previous write before issuing the next write then this will slow the sender down but I'm not 100% sure when the write completion is issued...
Better to have an explicit protocol...
Posted by: Len at June 5, 2007 04:00 PM