#include "spx_app.h"int t_snddis ( int spxFd, struct t_call *call)
spxFd
call
This function works as specified in ``Programming with the X/Open Transport Interface (XTI)''.
A t_snddis call generates an SPX/SPXII terminate connection request and releases all outstanding data messages on both the local and remote transport endpoint.
After an application issues a t_snddis, the application can do a t_unbind and t_close immediately without waiting.
SPX/SPXII doesn't support the function of sending address options or user data along with a disconnect request.
The correct procedure for terminating an SPX/SPXII connection is for both transport endpoints to correlate the moment that the connection is no longer needed, and then use t_snddis and t_rcvdis to terminate the connection or use orderly release now supported in SPXII.
The code samples illustrate the following:
{ .../* ** If you want to terminate the current connection and the ** state is T_DATAXFER, you do not need to send a pointer to ** the t_call structure. */
if(t_snddis(spxFd, (struct t_call *)NULL) < 0) { t_error( "t_snddis failed "); exit(-1); } ...
t_close(spxFd); }
/* ** If you wish to deny a connection request, you must supply the ** sequence number. The sequence number is in the sequence field of ** the t_call structure. The code below listens for connect request ** the uses the option structure returned by the listen to test if ** the other endpoint is using spxII. The t_listen sets the sequence ** field of the t_call structure, we use the same structure that ** t_listen returned to deny the connect request if the other ** endpoint is not using spxII. */{ struct t_call *rcvcall; SPX_OPTMGMT *retOpts; ...
if((rcvcall = (struct t_call *)t_alloc(spxFd, T_CALL,T_ALL)) == NULL) { t_error( "t_alloc of T_CALL failed"); exit(-1); }
listenAgain:
rcvcall->addr.len = rcvcall->addr.maxlen; rcvcall->opt.len = rcvcall->opt.maxlen; rcvcall->udata.len = 0;
/* ** Listen for a connect request */ if ((t_listen(spxFd, rcvcall)) < 0) { t_error( "t_listen failed"); exit(-1); }
/* ** Deny connection request if other endpoint is not spxII */ retOpts = (SPX2_OPTIONS *)rcvcall->opt.buf; if (!(retOpts->spxIISessionFlags & SPX_SF_SPX2_SESSION)) { rcvcall->addr.len = 0; rcvcall->udata.len = 0; rcvcall->opt.len = 0; if(t_snddis(spxFd, rcvcall) < 0) { t_error( "t_snddis failed "); t_free((char *)rcvcall, T_CALL); exit(-1); } ...
goto listenAgain; } t_free((char*)rcvcall, T_CALL); ... }