Hi,
I have played with this for a little while and been unable to resolve my issue.
Firstly, I am running MQX3.7 on the 52259evb.
My software is all fine and works as well as it can with the exception of OPT_CONNECT_TIMEOUT.
All I want to happen is connect() to return after 1 second if it fails to connect, but its always a couple of minutes which is way to long for our application.
I simply have the MQX RTCS connecting to my linux box or cygwin terminal. It Accepts connections using netcat listen on port 23 (nc -l 23) which works exactly as expected every time.
I have another UDP socket which is connected using similar methods and 100% works. this UDP issues commands such as RC:192.168.1.10:23 (Remote Connect to IP on port). This all works 100%. If my linux box is not listening, or, I try to connect to an unknown network like RC:199.199.199.199:10000 it just stays in 'connect()' for a couple of minutes regardless of what value I put in OPT_CONNECT_TIMEOUT.
Is my understanding of this wrong? Is this timer related to TCP packet time-outs? or some other timeout??
Here is a code snippet: (note there is some other code and messy debug info as I am just testing, the values of RC are global so they are not shown in the decleration)
//------------------------------------------------------
//This thread is called after another thread already has a UDP session attached and connected to my server which is where the RC: command comes from
void ETHRC_Task(uint_32)
{
sockaddr_in remote_sin;
uint_16 remote_len = sizeof(remote_sin);
uint_32 count;
uint_32 error;
uint_32 i = 0;
sockaddr_in local_sin; //Local address
uint_32 sock = 0;
int option = 0;
local_sin.sin_family = AF_INET;
local_sin.sin_port = ETHRC_HOST_PORT; //Get the port
local_sin.sin_addr.s_addr = INADDR_ANY;
// Create a datagram socket:
sock = socket(PF_INET, SOCK_STREAM, 0);
if (sock == RTCS_SOCKET_ERROR)
{
Write_Log((uchar*)STR_ERROR_CODE, ETH_SOCKET_CREATION_FAILED, 3, 0);
(uint_32)shutdown(sock, SOCKET_SHUT_PARAM);
_task_abort(MQX_NULL_TASK_ID);
}
printf("\nSocket configured\n");
i = sizeof(int);
option = TRUE; //Dont wait for data to come, just poll it
error = setsockopt(sock, SOL_TCP, OPT_RECEIVE_NOWAIT, &option, sizeof(option));
if(error != RTCS_OK) printf("Cannot set OPT_RECEIVE_NOWAIT %x\n", error);
error = getsockopt(sock, SOL_TCP, OPT_RECEIVE_NOWAIT, &option, (uint_32_ptr *)&i);
if(error != RTCS_OK) printf("getsockopt(OPT_RECEIEVE_NOWAIT) failed with error %x\n", error);
else printf("getsockopt OPT_RECEIEVE_NOWAIT = %X\n", option);
option = 1000; //5 second timeout on connections
error = setsockopt(sock, SOL_TCP, OPT_CONNECT_TIMEOUT, &option, sizeof(option));
if(error != RTCS_OK) printf("Cannot set OPT_CONNECT_TIMEOUT %x\n", error);
error = getsockopt(sock, SOL_TCP, OPT_CONNECT_TIMEOUT, &option, (uint_32_ptr *)&i);
if(error != RTCS_OK) printf("getsockopt(OPT_CONNECT_TIMEOUT) failed with error %x\n", error);
else printf("getsockopt OPT_CONNECT_TIMEOUT = %X\n", option);
// Bind the datagram socket to the UDP port:
error = bind(sock, &local_sin, sizeof(local_sin));
if (error != RTCS_OK) {
// ***FIX, log and restart task or manage proerly
//if(LiveLogDisplayLevel >= 4) printf("Bind fail\n");
Write_Log((uchar*)STR_ERROR_CODE, ETH_BIND_FAILED, 3, 0);
(uint_32)shutdown(sock, SOCKET_SHUT_PARAM);
_task_abort(MQX_NULL_TASK_ID);
}
printf("Socket Bind complete\n");
memset((char *) &remote_sin, 0, sizeof(sockaddr_in));
remote_sin.sin_family = AF_INET;
remote_sin.sin_port = ETHRC_HOST_PORT; //Port (same as local outgoing port)
remote_sin.sin_addr.s_addr = ETHRC_HOST_IP; //Server address
error = connect(sock, &remote_sin, sizeof(sockaddr_in));
if (error != RTCS_OK)
{
Write_Log((uchar*)STR_ERROR_CODE, ETH_REBIND_FAIL1, 3, 0);
(uint_32)shutdown(sock, SOCKET_SHUT_PARAM);
_task_abort(MQX_NULL_TASK_ID);
}
printf("Socket connected\n");
//------------------------------------------------------
Solved! Go to Solution.
Hi Carl,
Did you resolve this?
If not just tossing out random thoughts.
- Do you have KEEPALIVE active?
- I see other timeouts in the tcp.c file (part of TCP_Process_open() ) and wonder if they might be causing trouble at the tcb level?.
/* User timeout (R1) */
if ( coptions->utimeout >= 0 ) {
tcb->
sndto_1 = coptions->utimeout;
}
else {
tcb->
sndto_1 = 0;
}
/* Endif */
/* Connection timeout (R2) */
if ( coptions->timeout > 0 ) {
tcb->
sndto_2 = coptions->timeout;
}
else {
tcb->
sndto_2 = 2 * tcb->sndrtomax;
}
/* Endif */
.
.
.
/* Keepalive timeout */
if ( coptions->keepalive
> 0 ) {
tcb->
keepaliveto = coptions->keepalive
* 60000L;
}
else
{
tcb->
keepaliveto
= 0;
}
/* Endif */
The tcp.h has:
int_32 utimeout;
/* User timeout (msec) - TCP R1 period */
int_32 timeout; /* Connection timeout (msec) - TCP R2 period (use 0 to default) */
Comments in tcp.c:
/* Soft timeout (R1) must occur *before* hard timeout (R2) (see RFC1122
** section 4.2.3.5 for more details on these timeouts) */
The code here adjust the R1 to meet the above requirement.
Regards,
David
The code here adjust the R1 to meet the above requirement.
how can i modify the value of R1???
R1 corresponds with stream socket option OPT_SEND_TIMEOUT. You can use setsockopt() to modify this.
it's still not work.and this is my code :
i = 1;
i = setsockopt( sock, SOL_TCP, OPT_KEEPALIVE, &i, sizeof( i ) );
i = TCP_CONNECT_TIMEOUT / 2;
i = setsockopt( sock, SOL_TCP, OPT_SEND_TIMEOUT, &i, sizeof( i ) );
i = TCP_CONNECT_TIMEOUT;
i = setsockopt( sock, SOL_TCP, OPT_CONNECT_TIMEOUT, &i, sizeof( i ) );
I try to change the value of DEFAULT_CONNECT_TIMEOUT,and rebuild the all projects,but it still does not work!
when i shutdown the server program,connect() returns in several seconds.
but when i disconnect the cable,it always wait for a long time.
God,help me!:smileycry:
TCP_SENDTIMEOUT_MIN ok.
For some reason this forum wont let you edit the first post? weird...
Anyway, here is the consol output:
RC:192.168.2.20:10000 (this is nothing on my network or subnet)
Socket configured
getsockopt OPT_RECEIEVE_NOWAIT = 1
getsockopt OPT_CONNECT_TIMEOUT = 3E8
Socket Bind complete
ERROR CODE > 147 (2 minutes or so later, this is the error code on connect())
We have also notice this commend:
"Values ≥ 180,000 (RTCS maintains the connection for this number of milliseconds)."
So how do I stop RTCS maintaining the connection? I assume this is the problem...
Hi Carl, were you able to resolve this so that it times-out if it doesn't connect in 1s? How was it done?
Thanks
Hi Carl,
Did you resolve this?
If not just tossing out random thoughts.
- Do you have KEEPALIVE active?
- I see other timeouts in the tcp.c file (part of TCP_Process_open() ) and wonder if they might be causing trouble at the tcb level?.
/* User timeout (R1) */
if ( coptions->utimeout >= 0 ) {
tcb->
sndto_1 = coptions->utimeout;
}
else {
tcb->
sndto_1 = 0;
}
/* Endif */
/* Connection timeout (R2) */
if ( coptions->timeout > 0 ) {
tcb->
sndto_2 = coptions->timeout;
}
else {
tcb->
sndto_2 = 2 * tcb->sndrtomax;
}
/* Endif */
.
.
.
/* Keepalive timeout */
if ( coptions->keepalive
> 0 ) {
tcb->
keepaliveto = coptions->keepalive
* 60000L;
}
else
{
tcb->
keepaliveto
= 0;
}
/* Endif */
The tcp.h has:
int_32 utimeout;
/* User timeout (msec) - TCP R1 period */
int_32 timeout; /* Connection timeout (msec) - TCP R2 period (use 0 to default) */
Comments in tcp.c:
/* Soft timeout (R1) must occur *before* hard timeout (R2) (see RFC1122
** section 4.2.3.5 for more details on these timeouts) */
The code here adjust the R1 to meet the above requirement.
Regards,
David