Call WSACleanup()
drop the connection immediately.)
From the above discussion, UDP looks pretty useless, right? Well, it does have a few advantages over reliable protocols like TCP:
This makes UDP good for applications where timeliness and control is more important than reliability. Also, some applications are inherently tolerant of UDP problems. You have likely experienced blips, skips and stutters in streaming media programs: these are due to lost, corrupted or duplicated UDP frames.
Be careful not to let UDP’s advantages blind you to its bad points: too many application writers have started with UDP, and then later been forced to add reliability features. When considering UDP, ask yourself whether it would be better to use TCP from the start than to try to reinvent it. Note that you can’t completely reinvent TCP from the Winsock layer. There are some features of TCP like path MTU discovery that require low-level access to the OS’s networking layers. Other features of TCP are possible to duplicate over UDP, but difficult to get right. Keep in mind, TCP/IP was created in 1981, and the particular implementation you are using probably has code in it going back nearly that far. A whole lot of effort has gone into tuning this protocol suite for reliability and performance. You will be throwing away those decades of experience in trying to reinvent TCP or invent something better.
If you need a balance between UDP and TCP, you might investigate RTP (RFC 1889) and SCTP (RFC 2960). RTP is a higher level prototocol that usually runs over UDP and adds packet sequence numbers, as well as other features. SCTP runs directly on top of IP like TCP and UDP; it is a reliable protocol like TCP, but is datagram oriented like UDP.
5.不要在多个线程中对同一个socket调用send
Instead of multiple threads accessing a single socket, you may want to consider setting up a pair of network I/O queues. Then, give one thread sole ownership of the socket: this thread sends data from one I/O queue and enqueues received data on the other. Then other threads can access the queues (with suitable synchronization).
Applications that use some kind of non-synchronous socket typically have some I/O queue already. Of particular interest in this case is overlapped I/O or I/O completion ports, because these I/O strategies are also thread-friendly. You can tell Winsock about several OVERLAPPED blocks, and Winsock will finish sending one before it moves on to the next. This means you can keep a chain of these OVERLAPPED blocks, each perhaps added to the chain by a different thread. Each thread can also call WSASend()
on the block they added, making your main loop simpler.
6.If two threads in an application call recv()
on a socket,will they each get the same data?
No. Winsock does not duplicate data among threads.
No.
If two threads call WSAAsyncSelect()
on a single socket, only the thread that made the last call to WSAAsyncSelect()
will receive further notification messages.
If two threads call WSAEventSelect()
on a socket, only the event object used in the last call will be signaled when an event occurs on that socket.
You can’t trick Winsock by calling WSAAsyncSelect()
on a socket in one thread and WSAEventSelect()
on that same socket in another thread. These calls are mutually exclusive for any single socket.
You also cannot reliably call select()
on a single socket from two threads and get the same notifications in each, because one thread could clear or cause an event, which would change the events that the other thread sees.
As recommended above, you should give sole ownership of a socket to a single thread, then have it communicate with the other threads.