Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Need help on socket communication using UDP

Status
Not open for further replies.

nagarajv

Programmer
Sep 3, 2003
7
0
0
US

I am using sendto system to write
data to a socket on which the server is waiting on a select system call.

The first time my client writes data to the socket, the select system call on the server side returns but later again in a loop I write data to the same socket and for some reason the select call in the server does not seem to return. Please help me on this if anybody has any insight

Thanks
N
 
It's hard to say without seeing any code (from your description, I'm guessing you're using C). Some of us may be of help if you can post the pertinant server side code.

If that is not an option, consider using poll() instead of select().
 
In addition to the code please display the return code for select.
The error codes are meaningful.
The following is a short list:
WSANOTINITIALISED A successful WSAStartup() must occur before using this API.

WSAEFAULT The WinSock implementation was unable to allocate needed resources for its internal operations, or the readfds, writefds, exceptfds, or timeval parameters are not part of the user address space.

WSAENETDOWN The network subsystem has failed.

WSAEINVAL The timeout value is not valid, or all three descriptor parameters were NULL.

WSAEINTR A blocking WinSock 1.1 call was canceled via WSACancelBlockingCall().

WSAEINPROGRESS A blocking WinSock 1.1 call is in progress, or the service provider is still processing a callback function.

WSAENOTSOCK One of the descriptor sets contains an entry which is not a socket.
 
here is part of the code. This module receives the packet from the peer
and forwards it to the upper layer. Very first time it is started, the upper layer does receive the data and after that any subsequent messages it writes to the socket desc (appSD), the upper layer does not receive it.
on the other hand if I change the value of state variable to START_STATE in the block (if packet_type == DATA_PACKET), everything seems to be working fine.
It may be hard to decipher from this code snippet, but if you any questions please call me @408-802-5896 (Cell). I have to get this working ASAP.

Thanks,
N

static void sig_alrm(int signo)
{
write(pipefd[1], " ", 1);
printf("sig_alrm::TIMER went off \n");
return;
}

int createAckPacket(int sockfd, struct datagram *recvPacket, struct datagram *sendPacket)
{
printf("so_transport :: createAckPacket\n");
alarm(0);
removeACPHeader(recvPacket, sendPacket);
createAcknowledgementPacket(recvPacket);
Send(sockfd, sendPacket);
printf("string sent in createAckPacket = %s\n", sendPacket->buffer);
alarm(4);
return 0;
}

int main(int argc, char **argv) {
int sd, appSD, max_fd, n_ready, packetType;
int n;
int ACK_PENDING=0;
int state = START_STATE;
fd_set readFds;
char recvLine[MAXLENGTH];
char sendLine[MAXLENGTH];
static struct datagram recvPacket;
static struct datagram sendPacket;

struct sigaction new_action[1];
struct sigaction old_action[1];

new_action->sa_handler = sig_alrm;
sigemptyset(&new_action->sa_mask);
new_action->sa_flags = SA_RESTART;

sigaction(SIGALRM, new_action, old_action);

if (argc !=4 )
{
printf(&quot;usage : %s <server_UDP_Port, Application_UDP_Port, Application_IP_Address> \n&quot;, argv[0]);
exit(0);
}

pipe(pipefd);

if ((sd = CreateUDPSocket(atoi(argv[1]), NULL)) == NET_ERR)
{
printf(&quot;could not open UDP Socket \n&quot;);
exit(0);
}

if ((appSD = CreateUDPSocket(0, NULL)) == NET_ERR)
{
printf(&quot;could not open UDP Socket \n&quot;);
exit(0);
}

MakeDatagram(&recvPacket, recvLine, MAXLENGTH,0,NULL);
MakeDatagram(&sendPacket, sendLine, MAXLENGTH, atoi(argv[2]), argv[3]);

/* set up state machine */

int errorCode = FSMsetup(FSMtable, state);

if (errorCode != 0)
{
/* log a message */
printf(&quot;so_transport: could not set up FSM \n&quot;);
exit(1);
}
else {
printf(&quot;so_transport: successfully established state machine\n&quot;);
}

printf(&quot;FSM in so_transport \n&quot;);
FSMdisplay();

while (1) {
FD_ZERO(&readFds);
FD_SET(sd,&readFds);
FD_SET(appSD,&readFds);
FD_SET(pipefd[0], &readFds);

if (sd > appSD) {
max_fd = sd;
}
else {
max_fd = appSD;
}

printf(&quot;so_transport::main before select \n&quot;);

n_ready = select(max_fd+1,&readFds,NULL,NULL,NULL);
printf(&quot;so_transport::main select returns \n&quot;);

if (n_ready < 0 && errno == EINTR) {
printf(&quot;so_transport::main errno is EINTR and n_Ready less than 0\n&quot;);
continue;
}

if (FD_ISSET(appSD, &readFds)) {
if (Receive(appSD, &sendPacket) == NET_OK)
{
printf(&quot;Condition = %d, state = %d, appSD is selected \n&quot;, MESSAGE_SEND, state);
FSMaction(MESSAGE_SEND, &state, sd, &recvPacket, &sendPacket);
printf(&quot;state after the action = %d\n&quot;, state);
}
}

if (FD_ISSET(sd, &readFds)) {
if (Receive(sd, &recvPacket) == NET_OK) {
packetType = ProcessPacket(&recvPacket);
printf(&quot;SO_TRANSPORT MAIN: Packet Type = %d\n&quot;, packetType);
if (packetType == BAD_PACKET)
{
printf(&quot;so_transport: bad packet - dropping the packet\n&quot;);
/* drop the packet */
continue;
}
else if (packetType == DATA_ACK_PACKET)
{
printf(&quot;Packet type = DATA_ACK_PACKET \n&quot;);
printf(&quot;Condition = %d, state = %d, sd is selected \n&quot;, DATA_ACK_RECEIVED, state);
FSMaction(DATA_ACK_RECEIVED, &state, appSD, &recvPacket, &sendPacket);
printf(&quot;state after the action = %d\n&quot;, state);
}
else if (packetType == DATA_PACKET)
{
/*alarm(0);
state = START_STATE;
removeACPHeader(&recvPacket, &sendPacket);
createAcknowledgementPacket(&recvPacket);
Send(sd, &recvPacket);
Send(appSD, &sendPacket);
alarm(4);*/

printf(&quot;Packet type = DATA_PACKET \n&quot;);
printf(&quot;Condition = %d, state = %d, sd is selected \n&quot;, DATA_RECEIVED, state);
FSMaction(DATA_RECEIVED, &state, appSD, &recvPacket, &sendPacket);

printf(&quot;state after the action = %d\n&quot;, state);

/*from so_transport */
/*state=START_STATE;
removeACPHeader(&recvPacket, &sendPacket);
createAcknowledgementPacket(&recvPacket);
Send(sd, &recvPacket);
Send(appSD, &sendPacket);*/
}
else if (packetType == ACK_PACKET) {
printf(&quot;Packet type = ACK_PACKET \n&quot;);
printf(&quot;Condition = %d, state = %d, sd is selected \n&quot;, ACK_RECEIVED, state);
FSMaction(ACK_RECEIVED, &state, 0, &recvPacket, &sendPacket);
printf(&quot;state after the action = %d\n&quot;, state);
}
else if (packetType == NOT_DETERMINED)
{
printf(&quot;Packet type has not been determined\n&quot;);
/*drop the packet */
continue;
}
}
}

if (FD_ISSET(pipefd[0], &readFds)) {
read(pipefd[0], &n, 1); /* timer expired */
printf(&quot;Packet type = TIMER_EXPIRED \n&quot;);
printf(&quot;Condition = %d, state = %d, pipefd is selected \n&quot;, TIMER_EXPIRED, state);
FSMaction(TIMER_EXPIRED, &state, sd, &recvPacket, &sendPacket);
printf(&quot;state after the action = %d\n&quot;, state);
}

} /* while */
}
 

Does any body on how to debug this problem. Any help would be appreciated.

Thanks,
N
 

I guess WSAStartup is specific to windows and I have implemented this code under SuSe Linux. Also first time after invoking the server, it works fine just as it is supposed to be working. While still running, if select returns with data on socket descriptor sd, it tries to write the data on socket descriptor appSD. The second time in the loop the server1 sends(sendto) the datagram to server2 waiting on socket descriptor appSD, server1 does not get any response from server2.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top