问题
In theory nothing prevents using TCP socket with SOCK_DGRAM. What you'll get is reliable datagram transport. Is this possible using Berkeley sockets?
回答1:
What you want to take a look at is the SCTP Protocol. It provides the ability to send Datagrams over a reliable TCP style connection:
In contrast to TCP, SCTP may be characterized as record-oriented, meaning it transports data in terms of messages, in a similar fashion to the User Datagram Protocol (UDP), so that a group of bytes (message) sent in one transmission operation (record) is read exactly as that group at the receiver application. TCP is stream-oriented, transporting streams of bytes, which it correctly reorders in case of out-of-order delivery. It does not, however, honor message boundaries, i.e., the structure of data in terms of their original transmission units at the sender.
Take a look at SCTP one to one style connections which are probably what you're looking for.
There are implementations for most Unix / Linux OS and there is a third party implementation for Windows. See the end of the Wiki article I linked for details.
回答2:
SOCK_DGRAM as the type gets you a UDP socket. You can encapsulate UDP in TCP of course, but you'd have to handle the UDP part in userspace. Whether something is reliable depends on the protocol on the wire. If you use TCP, it is reliable; UDP is not.
To create a UDP socket:
int s;
s = socket(AF_INET, SOCK_DGRAM, 0);
To create a TCP socket:
int s;
s = socket(AF_INET, SOCK_STREAM, 0);
There are two common ways to send discrete chunks of data across the wire. You can either use UDP and send a discrete chunk as a datagram, or you can but structs into TCP data, and let them go as a stream. Using TCP is generally simpler and less failure-prone. If you use UDP, just time out and keep requesting the same data until you get it.
回答3:
In theory nothing prevents using TCP socket with SOCK_DGRAM. What you'll get is reliable datagram transport. Is this possible using Berkeley sockets?
No, Berkeley API provides unreliable datagram or reliable stream.
If you want to send reliable chunks over TCP use some protocol that splits stream into chunks. That is very simple to do.
回答4:
Not really. TCP and UDP are protocols from the same layer, and they have functions that make sense only to them. Take listen() and accept() for instance.
You could send UDP header+data inside TCP packets, but doesn't make sense at all. Why would you do that? A specie of tunnelling? In fact, it's very easy to parse and build UDP packets by hand, but I don't see a real application in your scenario.
回答5:
I've not seen any socket api that give you this option - and it would also defeat some of the purpose of TCP to let you control the data alignment. TCP is just the transport, and its abstraction is a byte stream.
You will have to build your own message structure on top of TCP that gives you the concept of messages that the application layer care about.
回答6:
You can simulate things, but there's really no reason to do so. Either you want reliable delivery or you want timely delivery. TCP gives you the first, UDP gives the second. The two can't mix because TCP implements reliability by repeatedly telling the other end about the messages until they're acknowledged. For streaming, you generally need reliable delivery of data (so you can reassemble the stream), but for small messages where order isn't important (i.e., datagrams) you don't need all that overhead (UDP does largely guarantee that messages at least won't arrive garbled; that's one of the things that both TCP and UDP offer over raw IP).
There are some other interesting cases between these two extremes, of course. For real-time streaming data (e.g., video calling), you use RTP because you're streaming but can recover from data loss better than delay. For messages that are too large for UDP (64kB is the strict upper-bound, since the UDP header only has 16 bits for its length field) you pretty-much need to use TCP for transport anyway so that you can reassemble the fragments (hence SOAP goes over HTTP over TCP, and not via UDP).
来源:https://stackoverflow.com/questions/2607696/is-it-possible-to-send-datagrams-over-tcp