async.c
来自「windows 网络编程。pdf文档」· C语言 代码 · 共 685 行 · 第 1/2 页
C
685 行
/* register for asynchronous notification of all events
* this socket could possibly get.(note: WSAAsyncSelect()
* will also make the socket non-blocking) */
wRet = WSAAsyncSelect(stWSAppData.nSock, hwnd, IDM_ASYNC,
(FD_READ | FD_WRITE));
if (wRet == SOCKET_ERROR) {
nb_close (hInst, hwnd);
WSAperror(WSAGetLastError(), "WSAAsyncSelect()", hInst);
}
/* convert port number from host byte order to network byte order */
stLclAddr.sin_port = htons (stWSAppData.nPortNumber);
stLclAddr.sin_addr.s_addr = 0L; /* don't restrict incoming address */
stLclAddr.sin_family = PF_INET; /* Internet Address Family */
wRet = bind(stWSAppData.nSock,
(struct sockaddr FAR*)&stLclAddr,
sizeof(struct sockaddr_in));
if (wRet == SOCKET_ERROR) {
nb_close (hInst, hwnd);
WSAperror(WSAGetLastError(), "bind()", hInst);
goto AppExit;
}
/*---------------------------------*/
stWSAppData.nSockState = STATE_BOUND;
/*---------------------------------*/
do_stats(hwnd, hInst, FALSE); /* update window to show current state */
AppExit:
return (wRet);
} /* end as_dg_ls */
/*---------------------------------------------------------------------------
* Function: as_w_r()
*
* Description:
* Asynch write and read. Our CLIENTS connecting to ECHO port use this.
*/
int as_w_r(HANDLE hInst, HANDLE hwnd)
{
int cbOutLen=0; /* Bytes in Output Buffer */
int cbBufSize; /* Length of I/O */
int nLoopLimit;
int i,wRet=0,nWSAerror;
cbBufSize = stWSAppData.nLength;
/* sound beep if I/O sound enabled */
if (stWSAppData.nOptions & OPTION_SOUND)
MessageBeep(0xFFFF);
/* Adjust the loops per I/O call */
LoopTimer(TRUE);
/* Read as much as we can first */
as_r(hInst, hwnd, DFLT_LOOP_MAX);
nLoopLimit = stWSAppData.nLoopsLeft ?
stWSAppData.nLoopsLeft : stWSAppData.nLoopLimit;
for (i=0; i<nLoopLimit; i++, stWSAppData.wOffset++) {
/* adjust offset into output string buffer */
if (stWSAppData.wOffset >= cbBufSize) {
stWSAppData.wOffset = 0;
}
cbOutLen = stWSAppData.nOutLen; /* pick-up where we left off */
stWSAppData.nOutLen = 0; /* reset marker */
/* write to server */
while (cbOutLen < cbBufSize) {
wRet = send (stWSAppData.nSock,
(LPSTR)&(achChargenBuf[stWSAppData.wOffset+cbOutLen]),
(cbBufSize-cbOutLen), 0);
if (wRet == SOCKET_ERROR) {
nWSAerror = WSAGetLastError();
if (nWSAerror != WSAEWOULDBLOCK) {
nb_close (hInst, hwnd);
WSAperror(nWSAerror, "send()", hInst);
}
/* Keep a marker, so we can pick-up where we leave off */
stWSAppData.nOutLen = cbOutLen;
stWSAppData.nLoopsLeft = nLoopLimit - i;
goto wr_end; /* exit on any error
(including WSAEWOULDBLOCK) */
} else {
/* Tally amount sent, to see how much left to send */
cbOutLen += wRet;
stWSAppData.lBytesOut += wRet;
/* stop if we've reached our limit */
if (stWSAppData.nBytesMax &&
(stWSAppData.lBytesOut >= stWSAppData.nBytesMax)) {
do_close(hInst, hwnd, FALSE);
goto wr_end;
}
}
} /* end send() loop */
} /* end main loop */
/* Send OOB Data if we want to */
if (stWSAppData.nOptions & OPTION_OOBSEND) {
nb_oob_snd (hInst, hwnd);
}
/* init to normal value (we completed all iterations) */
stWSAppData.nLoopsLeft = stWSAppData.nLoopLimit;
wr_end:
LoopTimer(FALSE); /* set exit time from I/O loop */
return (cbOutLen);
} /* end as_w_r() */
/*---------------------------------------------------------------------------
* Function: as_r_w()
*
* Description:
* Asynch read and write. Our SERVERS providing ECHO service use this.
*/
int as_r_w(HANDLE hInst, HANDLE hwnd)
{
int cbInLen; /* Bytes in Input Buffer */
int cbOutLen=0; /* Bytes in Output Buffer */
int cbBufSize; /* Length of I/O */
int i, wRet, nWSAerror;
cbBufSize = stWSAppData.nLength;
if (stWSAppData.nOptions & OPTION_SOUND)
MessageBeep(0xFFFF);
for (i=0, recv_count=0; i<stWSAppData.nLoopLimit; i++) {
/* read as much as we can from client (no less than I/O length
* user requested, but more than that is ok) */
cbInLen = 0;
while (cbInLen < cbBufSize) {
wRet = recv (stWSAppData.nSock,
(LPSTR)&(achInBuf[cbInLen]), BUF_SIZE-cbInLen, 0);
recv_count++; /* count recv() calls */
if (wRet == SOCKET_ERROR) {
nWSAerror = WSAGetLastError();
if (nWSAerror != WSAEWOULDBLOCK) {
nb_close (hInst, hwnd);
WSAperror(nWSAerror, "send()", hInst);
goto rw_exit;
}
/* exit recv() loop on WSAEWOULDBLOCK */
if (cbInLen == 0)
goto rw_exit; /* quit if nothing read yet */
else
break; /* else write out what we read */
} else if (wRet == 0) { /* Other side closed socket */
MessageBox (hwnd, achOutBuf,
"client closed connection", MB_OK);
do_close (hInst, hwnd, FALSE);
goto rw_exit;
} else {
cbInLen += wRet;
stWSAppData.lBytesIn += wRet;
/* stop if we've reached our limit */
if (stWSAppData.nBytesMax &&
(stWSAppData.lBytesIn >= stWSAppData.nBytesMax)) {
do_close(hInst, hwnd, FALSE);
break;
}
}
} /* end recv() loop */
/* write to client, as much as we just read */
cbOutLen = 0;
while (cbOutLen < cbInLen) {
wRet = send (stWSAppData.nSock,
(LPSTR)&(achInBuf[cbOutLen]),
(cbInLen-cbOutLen), 0);
if (wRet == SOCKET_ERROR) {
nWSAerror = WSAGetLastError();
if (nWSAerror != WSAEWOULDBLOCK) {
nb_close (hInst, hwnd);
WSAperror(nWSAerror, "send()", hInst);
goto rw_end;
}
break;
} else if (wRet == 0) {
/* not likely, but possible */
break;
}
/* Tally amount sent, to see how much left to send */
cbOutLen += wRet;
stWSAppData.lBytesOut += wRet;
} /* end send() loop */
} /* end main loop */
rw_end:
/* Datagram Servers aren't "connected" until data arrives,
* so change it now (and start timer) */
if ((stWSAppData.nSockState < STATE_CONNECTED) &&
(stWSAppData.nSockState > STATE_NONE)) {
/*--------------------------------------*/
stWSAppData.nSockState = STATE_CONNECTED;
/*--------------------------------------*/
/* get timers for statistics updates & I/O (if requested) */
get_timers(hInst, hwnd);
}
rw_exit:
return (cbOutLen);
} /* end as_r_w() */
/*---------------------------------------------------------------------------
* Function: as_r()
*
* Description:
* Asynch read
*/
int as_r(HANDLE hInst, HANDLE hwnd, int nLoopLimit)
{
int cbInLen;
int i, wRet, nWSAerror;
if (stWSAppData.nOptions & OPTION_SOUND)
MessageBeep(0xFFFF);
for (cbInLen=0, recv_count=0, i=0; i<nLoopLimit; i++) {
/* read as much as we can from server (no less than I/O length
* user requested, but more than that is ok) */
wRet = recv (stWSAppData.nSock,
(LPSTR)achInBuf, BUF_SIZE, 0);
recv_count++; /* count recv() calls */
if (wRet == SOCKET_ERROR) {
nWSAerror = WSAGetLastError();
if (nWSAerror != WSAEWOULDBLOCK) {
nb_close (hInst, hwnd);
WSAperror(nWSAerror, "send()", hInst);
}
break; /* break on any error (including WSAEWOULDBLOCK) */
} else if (wRet == 0) { /* Other side closed socket */
/* if we're connected, tell user and close */
MessageBox (hwnd, achOutBuf,
"server closed connection", MB_OK);
do_close(hInst, hwnd, FALSE);
break;
} else {
/* tally amount received */
cbInLen += wRet;
stWSAppData.lBytesIn += wRet;
/* stop if we've reached our limit */
if (stWSAppData.nBytesMax &&
(stWSAppData.lBytesIn >= stWSAppData.nBytesMax)) {
do_close (hInst, hwnd, FALSE);
break;
}
}
} /* end main loop */
/* Datagram Servers aren't "connected" until data arrives,
* so change it now (and start timer) */
if ((stWSAppData.nSockState < STATE_CONNECTED) &&
(stWSAppData.nSockState > STATE_NONE)) {
/*--------------------------------------*/
stWSAppData.nSockState = STATE_CONNECTED;
/*--------------------------------------*/
get_timers(hwnd, hInst);
}
return (cbInLen);
} /* end as_r() */
/*---------------------------------------------------------------------------
* Function: as_w()
*
* Description:
* Asynch write
*/
int as_w(HANDLE hInst, HANDLE hwnd)
{
int cbOutLen=0; /* Bytes in Output Buffer */
int cbBufSize; /* Length of I/O */
int i, wRet, nWSAerror;
cbBufSize = stWSAppData.nLength;
if (stWSAppData.nOptions & OPTION_SOUND)
MessageBeep(0xFFFF);
for (i=0; i<stWSAppData.nLoopLimit; i++, stWSAppData.wOffset++) {
/* adjust offset into output string buffer */
if (stWSAppData.wOffset >= cbBufSize) {
stWSAppData.wOffset = 0;
}
/* write to server */
cbOutLen = 0;
while (cbOutLen < cbBufSize) {
wRet = send (stWSAppData.nSock,
(LPSTR)&(achChargenBuf[stWSAppData.wOffset+cbOutLen]),
(cbBufSize-cbOutLen), 0);
if (wRet == SOCKET_ERROR) {
nWSAerror = WSAGetLastError();
if (nWSAerror != WSAEWOULDBLOCK) {
nb_close (hInst, hwnd);
WSAperror(nWSAerror, "send()", hInst);
}
break; /* break on any error. If WSAEWOULDBLOCK,
* then FD_WRITE will restart sending */
} else {
/* Tally amount sent */
cbOutLen += wRet;
stWSAppData.lBytesOut += wRet;
/* stop if we've reached our limit */
if (stWSAppData.nBytesMax &&
(stWSAppData.lBytesOut >= stWSAppData.nBytesMax)) {
do_close (hInst, hwnd, FALSE);
break;
}
}
} /* end send() loop */
} /* end main loop */
/* Send OOB Data if we want to */
if (stWSAppData.nOptions & OPTION_OOBSEND) {
nb_oob_snd (hInst, hwnd);
}
return (cbOutLen);
} /* end as_w() */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?