Solved

How to send separate TCP packets to socket

Posted on 2001-08-02
16
495 Views
Last Modified: 2012-08-14
Hi,
  I need to send a stream of data immediately after another data is sent, but in different TCP packet.  


That means:

Send(sock1, data1, ...);
Send(sock1, data2, ...);

Currently these two data will appear in a single TCP packet ( I captured it from network monitor).

Is there any way to force the winsock to break these as two packet, or any function such as flush() that can be called before I send the data2.

Thank you.
0
Comment
Question by:lsmgms
  • 4
  • 4
  • 3
  • +3
16 Comments
 
LVL 3

Expert Comment

by:cwrea
ID: 6347124
Try setsockopt() with the TCP_NODELAY option.  Here's the description from MSDN:

TCP_NODELAY
The TCP_NODELAY option is specific to TCP/IP service providers. The Nagle algorithm is disabled if the TCP_NODELAY option is enabled (and vice versa). The process involves buffering send data when there is unacknowledged data already "in flight" or buffering send data until a full-size packet can be sent. It is highly recommended that TCP/IP service providers enable the Nagle Algorithm by default, and for the vast majority of application protocols the Nagle Algorithm can deliver significant performance enhancements. However, for some applications this algorithm can impede performance, and TCP_NODELAY can be used to turn it off. These are applications where many small messages are sent, and the time delays between the messages are maintained. Application writers should not set TCP_NODELAY unless the impact of doing so is well-understood and desired because setting TCP_NODELAY can have a significant negative impact on network and application performance.


Do a search on the word "Nagle" in MSDN to find out more.

Hope this helps.
0
 
LVL 3

Expert Comment

by:stimpyjcat
ID: 6347265
Perhaps what you mean is they appear in a single IP packet.  TCP has no concept of packets, it is a stream-based protocol which means that the stream of bytes you feed in one end is the exact same stream you get out the other end.

If you want to delineate messages within the stream, you need add your own meta information, e.g. prefixing each "message" with the coming message's length, so that the receiving end can split the stream up into messages again.
0
 
LVL 3

Expert Comment

by:stimpyjcat
ID: 6347282
Oh, btw, if you really just want to send discrete messages, consider using UDP (SOCK_DGRAM) instead.
0
 
LVL 6

Expert Comment

by:thienpnguyen
ID: 6347311
You can not. In fact, TCP is called a stream socket.
Therefore, when you send 2 packets with sizes 1000 bytes
and 2000 bytes. These have  the following cases at receiver

    1.  Receive 2 packets with same sizes as sender : 1000 and 2000
   
    2.  Receive 2 packets with not same sizes as sender.
        Maybe, first packet is 1700 bytes and second packet is 1300
   
    3. Receive only one packet 3000 bytes

You  can have your require, if you use UDP socket                      
0
 
LVL 1

Author Comment

by:lsmgms
ID: 6347803
Thanks for reply.  However I cannot move to UDP because the protocol (ITU-T H.225.0) has to run on TCP.
0
 
LVL 10

Expert Comment

by:makerp
ID: 6347886
the easiest way to do this is just recv a set amount at the other end, for example you want to send 2 packets , the first 15 bytes, and the second 25, and you dont want them to join up. so

send the first packet as normal then at the receving end simply call recv with a buffer size of 15, this way at most recv will only return 15, no more leaving the other packet in the socket wating for your next call of 25.

a generic way to solve this problem is with the following simple yet effective application level protocol

first send an int saying how much is in the next packet
then send the packet

on the recver simply

recv one int first
then recv the amount specified by the first int

you can write two functions to wrap this, then if both client and server use them you have s simple app level protocol

int send(char *buffer, int len)
{
  send (value of len);
  send (buffer)
}

int recv(char *buffer)
{
  recv (amount_to_follow)
  recv(buffer, amount_to_follow)
}

using this approach it is easy to bound each packet withour regard to what winsock does to them. i have done loads of socket programming and i have sent packets like you describe all the time

>>Try setsockopt() with the TCP_NODELAY option.  Here's the description from MSDN

THIS WONT HELP
0
 
LVL 3

Expert Comment

by:cwrea
ID: 6348531
It seems many of you have made the assumption the poster wants to see the data in such-and-such a way on the other end, at the application level.  You're all right that he'll have to do something in his protocol to deal with that.

However, he stated he is using a network monitor and wants them to appear in separate packets.  Dealing at that level, I believe disabling the Nagle algorithm is entirely appropriate and will accomplish the stated goal.  It might not change the way the other end deals with the data at the application layer, but it should certainly change the way the data is transmitted in packets over the network layer.

So, now I'm very curious :-)  Ismgms, *why* is it you want to have the data appear in separate packets?  Do you have control over both sides of the application?  What kind of application is it?  What problem are you trying to solve?  Perhaps you've given us only a symptom of the problem?  i.e. perhaps you've got some bigger-picture problem, and have already gone partway down one possible path and are asking for help with that path?  If so what is the bigger-picture problem?


0
 
LVL 10

Expert Comment

by:makerp
ID: 6348629
ok, point taken, i was hasty to post an answer here, i should have thought about the question more, please reject it to open this up for more input.

yes you are right, packets at the network level are entirerly different from application defined packets.
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 3

Expert Comment

by:stimpyjcat
ID: 6348851
I doubt he actually needs separate packets on the network, but he can speak for himself.  I've seen many programmers start using sockets with the mistaken assumption that for each chunk that gets sent on one end, you will read the same chunk at the other end, and build upon that assumption.  Depending on the actual activity involved, it may actually work for a while.
0
 
LVL 30

Expert Comment

by:Axter
ID: 6354782
Hi (lsmgms):
Feel free to click the [Reject Answer] button near (Answer-poster's) response, even if it seems like a good answer.
Doing so will increase your chance of obtaining additional input from other experts.  Later, you can click the [Select Comment as Answer] button on any response.
0
 
LVL 1

Author Comment

by:lsmgms
ID: 6374756
Hi,

Thanks for help again.

As mentioned before, the protocol is ITU-T H.225.0, which used in VOIP. So, the suggestion from makerp will not work for me.  All of the receivers are using this standard, including CISCO and Microsoft netmeeting, and perhaps other video conferencing application.

I need to separate the packets because the network analysis (Ethereal) seems has confused with the packets  (For information, ITU-T H.225.0 is using Packed Encoded Rules ASN), and decode the packets wrongly, although in the TCP layer I can see the data has transmitted correctly.  Of cource I can ignore this problem because it may be a bug from Ethereal, but I am not sure whether other receipient will decode it wrongly also.  

Currently I put a Sleep(1000) in between send().  However, this is not a good idea.

Thanks again.
0
 
LVL 6

Expert Comment

by:thienpnguyen
ID: 6374795
www.openh323.org implements the h232 protocol that includes h225 protocol.
That stuff is open source code, free and very good .  Many companies use
openh323 for their product. It is better you use that free stuff. If you don't want,
you can read openh323 source to know how it is implemented.



0
 
LVL 3

Accepted Solution

by:
cwrea earned 50 total points
ID: 6376253
lsmgms, did you try my earlier suggestion?

0
 
LVL 1

Author Comment

by:lsmgms
ID: 6378358
thienpnguyen,
Yes,  I have came accross the site before I started the project.
Thanks.

cwrea,
Sorry, I am a bit late.  I will try it now.
Thanks.
0
 
LVL 1

Author Comment

by:lsmgms
ID: 6378425
cwrea,
  Thanks.  It works already.
0
 
LVL 3

Expert Comment

by:cwrea
ID: 6380251
Great.  I'm glad it worked for you.

0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now