|
Hi,
I used UDT::select in a program, but it doesn't work the way it's supposed to. the server (use the UDT::select) listening on sockfd 3 for example, and then it only accept ONE connect(sockfd 4), after that all the listenning are base on sockfd 4, no sockfd 3 is listening.
I checked the source code of UDT, and found that server listend on sockfd 3(stored in a variable called m_iSocket) in the very beginning, when the first connect is comming, server accepted it, and change the m_iSocket to 4, so any new connection could not connect to the server successful and will "time out" in the end.
Is there anybody could give me a hand ?
..........
|
|
|
|
|
|
Hint:
Use UDT v3.3
the UDT-m/UDT v4 did not work well at the moment.
- Jens Schneeweiß, www.schneeweiss.de
www.schneeweiss.de
|
|
|
|
|
I am using the UDP-based Data Transfer Protocol with UDT-m/UDT v4, !
But sometimes it crashes in some map / vector functions inside the udt.dll !
I think it is a conflict with the Queue and Multithreading.
Did someone use the UDT-m and it works better?
- Jens Schneeweiß www.schneeweiss.de
www.schneeweiss.de
|
|
|
|
|
I am currently working on a project and i am asked to "break" udt protocol from application, what i mean exactly is to make two different exes (one for protocol and one for application) and make them correspond with each other through pipes or something like that. I am newbie to newtwork programming so any help would be appreciated!
|
|
|
|
|
Hello lilyco, Hing,
I would like to understand if I can use multiple UDT sockets in parallel? I would like to maintain several (2-5) UDT connections at the same time. Is this possible?
If not , would you please suggest me how to start to understand your code and how to add this feature?
Thanks a lot,
Wee.
|
|
|
|
|
Hi:
I have a question about UDT, I see the document in http://udt.sourceforge.net/doc/index.htm
which says :
While UDT was originally written for extremely high speed data transfer, there are many other potential benefits from this reliable UDP-based library. One particular usage is to setup reliable connections between machines behind firewalls, especially those NAT firewall. To meet this requirement, UDT has added the rendezvous connection setup support.
It seems UDT only support punching Firewall/NAT only in Rendezvous mode , is that right?
|
|
|
|
|
Hello lilyco,
I need your suggestion. I want to understand the source code and want to add support to Rendezvous mode so that it supports "one port to multiple connections". I am a newbie to your code and would you think it is hard to do so? Or would you please suggest me how to start to understand your code and how to add this feature?
Thanks a lot.
Hing
|
|
|
|
|
While it is not very difficult, there is no simple way to do it. First, you have to write a UDP multiplexer that deals with multiple connection sending and receiving. Once you have this ready, you can use it to replace the regular UDP channel as in channel.h.
I didn't use this method because it brings some additional overhead and it is not desirable in high performance computing area that UDT was originally designed for. I may use it in next UDT version if the overhead is proved to be very limited.
|
|
|
|
|
Thanks for your quick response, I just started looking at channel.cpp. However, I will have few questions before going further:
I found that you will have a "::connect" routine under UDP. Is that in Rendzvous mode, the "UDT::connect" will call the "::connect"? My concern is, since under UDP, if you call "::connect", it is just for one peer connection. According to the document of UNIX, "connect" under UDP mode only support one peer.
So, in order to support multiple connection for 1 port, either side should call connect, right? And go back to have connectionless design, but with your reliable messaging feature?
Or the design should be, still have connection-oriented design, but need one to be server which need to do bind->listen->accept action to accept connection under Rendezvous mode?
Or I still not yet fully understand your design? Coz I am just looking at your channel.cpp, not yet finished. I just want to tell some of my concern first and hope it may raise your awareness if there is any.
|
|
|
|
|
Sorry, as the thread is becoming large so, I post my question here:
Problem:
While in rendezvous mode, when you do connect in a separate thread and the connect is blocking (waiting another to connect in), and you do UDT::close to close the socket which is being used in that thread by the "connect" function, the close function just blocked until the connection timeout in that thread.
Is that normal? Because I expect that whenever I call UDT::close, any socket operation should be abandoned and return immediately.
Also, are you working on the problem in the thread below?
http://www.codeproject.com/internet/udt.asp?msg=1577366#xx1577366xx[^]
Thanks for your kind attention and I am looking forward to you.
Hing
|
|
|
|
|
In UDT, "close" does not return immediate but wait until other process (connect, send, recv, etc) to finish or timeout (see LINGER option). I did make a small change so that "close" will return very soon in the case you metioned. All the new code can be found in sourceforge CVS.
|
|
|
|
|
Hello lilyco,
I tried the following:
----------------------------------------------------------------
1. A do: (INIT socket as SOCK_STREAM->Bind <localhost> 9999->Listen 10->Accept->Recv if client connect)
2. B do: (INIT socket as SOCK_STREAM->Bind <localhost> 8888->Connect <localhost> 9999)
3. They connected and I tried to send message in between, it succeed.
4. If B is killed, A's "Recv" function doesn't return, and when A try to send message to the client B, it succeed (i.e. The "Send" function return ok), but I expect that it can detect the socket is broken.
5. After a minutes, A's "Recv" return:
Error Code: 2001, Error Msg: Connection was broken
--------------------------------------------------------------------
However, if i do "UDT::close" on B, the A can detect the connection broken immediately, is that I should always do "UDT::close"?
Thx a lot
-- modified at 23:20 Wednesday 12th July, 2006
|
|
|
|
|
In the first case, A uses timeout to detect the broken connection, because B is killed and A doesn't know. The time to detech broken connection varies, depending on the delay between A and B.
For a regular send, A simply copies the data into the protocol buffer and returns, so "send" does not know the error. If you use overlapped send, which wait until the data is actually sent to the peer side, it will detect the error.
In the second case, since you explicitly close B, which will send a shutdown msg to A before exit, A therefore will know it immediately.
|
|
|
|
|
Hello lilyco,
I have 1 questions:
I tried overlapped send by doing following:
-----------------------------------------------------------------
/////
void DeleteBuf(char* buf, int a)
{
// do nothing
}
/////
int handle = 1;
char buf[] = "hello";
if(UDT::ERROR == UDT::send(recver, buf, strlen(buf), 0, &handle, (UDT_MEM_ROUTINE)DeleteBuf))
{
....
}
The "send" function return successfully even B is killed.
-------------------------------------------------------
Thx a lot.
-- modified at 2:38 Thursday 13th July, 2006
|
|
|
|
|
sorry, my mistake. overlapped send will also return immediately unless the send buffer is full. You can use getoverlappedresult to check if the send if completed.
|
|
|
|
|
Sorry, I have question again.
I tried the following:
1. B: (INIT Sock as SOCK_STREAM->Set Rendevzous mode->Bind->Connect (waiting A))
2. A: (INIT Sock as SOCK_STREAM->Set Rendevzous mode->Bind->Connect (connected to B))
3. B exit
4. A try to send overlap with message "ABC", it return true, then, i call getoverlapresult as follow:
int progress;
bool bwait = true;
bool bResult = UDT::getoverlappedresult(udtsock, handle, progress, bwait);
The function just wait here. After a while, it return false with error code "0" and progress "0". But I expect that the error code shouldn't be zero and telling me why send fail.
I tried to set bwait as false, the function return false immediately with error code "0" and progress "0" again. But I expect that progress should be "-1" according to your documentation of "getoverlappedresult".
Thanks for your attention.
|
|
|
|
|
If wait == true, then an error code should be returned. I have updated the code to reflect this change.
If wait == false, in the situation you metioned, A does not know the connection is broken yet, so A will return progress 0 (nothing is sent). If you try this call a moment later, once the broken connection is detected, progress should be -1.
|
|
|
|
|
Hello lilyco,
I would like to ask first if you will reply faster in codeproject forum or in sourceforge forum? As I saw someone post the same question in the sourceforge forum as well and you have a reply there, anyway, let me ask the question first:
In the help page of rendezous connection, I found that the information is not enough, for connection behind NAT, in the past, I would do like below using UDP:
1. For example, 192.168.0.2:5000 (named: A) wants to talk to 10.0.0.2:5000 (named: B) and both are behind NAT firewall.
2. There is a public known server 221.127.209.250 (named: C) which in otherwise stored the NAT address and port of A and B.
3. A and B go to the C to get the NAT address of each other
4. A try to send B a data using the NAT address of B and so, NAT router of A will build a NAT tuple (addr of A, port of A, addr of A's NAT, port of A's NAT, NAT addr of B, NAT port of B) (The data won't arrive as B's NAT didn't build the tuple yet)
5. B try to send A a data using the NAT address of A and so, NAT router of B will build a NAT tuple (addr of B, port of B, addr of B's NAT, port of B's NAT, NAT addr of A, NAT port of A)
6. Then, A and B can talk to each other by sending data using their NAT address and port. (As tuples are built in both NAT)
So, the above algorithm only work on UDP as only UDP can make sure both terminate use the fixed port (by using 'bind').
So, under UDT, what is the step we should do?
|
|
|
|
|
1. create a UDP socket on A, bind to 5000, send any necessary message to C, so that C knows the the NAT address of UDP A:5000.
2. by the same way, C will know the NAT address of UDP B:5000.
3. close the UDP socket created in 1) and 2).
4. A and B obtain the other's NAT address from C
5. create UDT socket on A, bind it to 5000, set UDT_RENDZEVOUS option to true
6. do the same thing on B
7. On A, use UDT connect call to connect to the NAT address of B; On B, use UDT connect call to connect to the NAT address of A.
|
|
|
|
|
Thx a lot, I didn't try yet, but I want to ask, in step 1, can I use UDT socket instead of UDP? Is there any different? Thx a lot.
|
|
|
|
|
Hello lilyco,
I am stuck in step 7. After I do all the things (step 1 to step 6), I tried to call connect, however, it just return saying that "connection timeout". I just wonder, in RENDZEVOUS mode, no one is able to call Listen or Accept, so, the "connect" function conceptually connect to nothing, right?
So, what can I do ... In fact, I tried in a public server and a machine under NAT below:
1. There is a public server (S) and a machine (A) under NAT.
2. I start a simple UDP server,S, in the public server.
3. A first bind (192.168.101.167:5000) and then connect to S using simple UDP connection and send some dummy message to S so that S get A's NAT address and port (123.123.123.123:19876)
4. I close the UDP connection in A and start UDT connection by doing:
init socket as SOCK_STREAM->set rendezvous to 1->bind to the address (192.168.101.167:5000)
5. I start a UDT application B in the *public server* and do about the same thing:
init socket as SOCK_STREAM->set rendezvous to 1->bind to a randome address (123.123.123.123:9000)
6. In B, I tried to connect to A by connecting to A's NAT address and port, but it return "connection timeout", and same thing happen in the side of A.
So, is that I missed some step ?
|
|
|
|
|
RENDEZVOUS connect is different from the regular connect. In RENDEZVOUS mode, A and B have to connect to each other, i.e., they must both call "connect". If B connect to A while is doing nothing, then B indeed connect to nothing.
BTW, in step 1 & 2, you can use any methods to obtain the NAT address, including using UDT socket.
|
|
|
|
|
Hello lilyco,
Thanks a lot. I succeed to connect to each other (ie Both "connect" return successfully ). However, I fail to send message to each other, what is the problem? I open the socket using SOCK_STREAM, and send a message "hello" by using the same UDTSOCKET in the whole procedure (i.e. Init the socket->Set Rendezous->Bind->Connect).
After connection succeed, I call recv, the function is blocking and waiting for message, the other side try to send message by using "send", the send function return successfully. However, in the receiving side, nothing received (i.e. the "recv" function never return).
After a while, the "recv" function return with the following error:
Error code:2001
Erro msg: Connection was broken
and when the other side try to send data to the receiving side, the "send" fail with the above error also.
So, when I do all the step again, it succeed to connect, but fail to send and receive message. So, what is the problem?
Thx a lot
|
|
|
|
|
Hi, thanks for the information. I just checked the code and found out that my recent changes had introduced a new bug for rendezvous connection. I have fixed it now. Please check out the new code from sourceforge CVS area and try again.
-- modified at 1:57 Wednesday 12th July, 2006
or, in core.cpp, make the following change.
+ 719 if (!m_bRendezvous)
+ 720 {
721 if (AF_INET == m_iIPversion)
722 addr4.sin_port = htons(res->m_iPort);
723 else
724 addr6.sin6_port = htons(res->m_iPort);
+ 725 }
|
|
|
|
|