📄 blocking.c
字号:
else
return(0);
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 blocking call canceled then close, else report error */
if (nWSAerror == WSAEINTR) {
bl_close(hInst, hwnd);
} else {
bl_close(hInst, hwnd);
WSAperror(nWSAerror, "send()", hInst);
}
} else {
/* Tally amount sent, to see how much left to send */
cbOutLen += wRet;
stWSAppData.lBytesOut += wRet;
}
} /* end send() loop */
/* read from server (hopefully what we just wrote) */
cbInLen = 0;
while (cbInLen < cbBufSize) {
wRet = recv (stWSAppData.nSock, (LPSTR)achInBuf,
(BUF_SIZE-cbInLen), 0);
if (wRet == SOCKET_ERROR) {
nWSAerror = WSAGetLastError();
/* if blocking call canceled then close, else report error */
if (nWSAerror == WSAEINTR) {
bl_close(hInst, hwnd);
} else {
bl_close(hInst, hwnd);
WSAperror(nWSAerror, "recv()", hInst);
}
goto wr_end;
} else if (wRet == 0) { /* Other side closed socket */
MessageBox (hwnd, achOutBuf,
"server closed connection", MB_OK);
goto wr_end;
} else {
cbInLen += wRet;
stWSAppData.lBytesIn += wRet;
}
} /* end recv() loop */
} /* end main loop */
wr_end:
/* Tell ourselves to do it again (if we're not
* using a timer and we're still connected)! */
if (!stWSAppData.nWinTimer &&
(stWSAppData.nSockState == STATE_CONNECTED))
PostMessage(hwnd, WM_COMMAND, IDM_WRITE_READ, 0L);
bBusy=FALSE; /* reset busy flag */
return (cbOutLen);
} /* end bl_w_r() */
/*---------------------------------------------------------------------------
* Function: bl_r_w()
*
* Description:
* Blocking read and write. Our SERVERS providing ECHO service use this.
*/
int bl_r_w(HANDLE hInst, HANDLE hwnd)
{
int cbInLen; /* Bytes in Input Buffer */
int cbOutLen; /* 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++) {
/* read from client */
cbInLen = 0;
while (cbInLen < cbBufSize) {
wRet = recv (stWSAppData.nSock,
(LPSTR)achInBuf, (cbBufSize-cbInLen), 0);
if (wRet == SOCKET_ERROR) {
nWSAerror = WSAGetLastError();
/* if blocking call canceled then close, else report error */
if (nWSAerror == WSAEINTR) {
bl_close(hInst, hwnd);
} else {
bl_close(hInst, hwnd);
WSAperror(nWSAerror, "recv()", hInst);
}
goto rw_end;
} else if (wRet == 0) { /* Other side closed socket */
MessageBox (hwnd, achOutBuf,
"client closed connection", MB_OK);
goto rw_end;
} else {
cbInLen += wRet;
stWSAppData.lBytesIn += wRet;
}
} /* end recv() loop */
/* write to client */
cbOutLen = 0;
while (cbOutLen < cbBufSize) {
wRet = send (stWSAppData.nSock,
(LPSTR)&(achInBuf[cbOutLen]),
(cbBufSize-cbOutLen), 0);
if (wRet == SOCKET_ERROR) {
nWSAerror = WSAGetLastError();
/* if blocking call canceled then close, else report error */
if (nWSAerror == WSAEINTR) {
bl_close(hInst, hwnd);
} else {
bl_close(hInst, hwnd);
WSAperror(nWSAerror, "send()", hInst);
}
goto rw_end;
} else {
/* Tally amount sent, to see how much left to send */
cbOutLen += wRet;
stWSAppData.lBytesOut += wRet;
}
} /* end send() loop */
} /* 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_CONNECTED;
/*-------------------------------------*/
/* get timers for statistics updates & I/O (if requested) */
get_timers(hInst, hwnd);
}
rw_end:
/* Tell ourselves to do it again (if we're not
* using a timer and we're still connected)! */
if (!stWSAppData.nWinTimer &&
(stWSAppData.nSockState == STATE_CONNECTED)) {
PostMessage(hwnd, WM_COMMAND, IDM_READ_WRITE, 0L);
}
return (cbOutLen);
} /* end bl_r_w() */
/*---------------------------------------------------------------------------
* Function: bl_r()
*
* Description:
* Blocking read
*/
int bl_r(HANDLE hInst, HANDLE hwnd)
{
int cbInLen=0; /* Bytes in Input Buffer */
int cbBufSize; /* Length of I/O */
char achInBuf [BUF_SIZE]; /* Input Buffer */
int i, wRet, nWSAerror;
cbBufSize = stWSAppData.nLength;
if (stWSAppData.nOptions & OPTION_SOUND)
MessageBeep(0xFFFF);
for (i=0; i<stWSAppData.nLoopLimit; i++, stWSAppData.wOffset++) {
/* read from server */
cbInLen = 0;
while (cbInLen < cbBufSize) {
wRet = recv (stWSAppData.nSock,
(LPSTR)achInBuf,
(cbBufSize-cbInLen), 0);
if (wRet == SOCKET_ERROR) {
nWSAerror = WSAGetLastError();
/* if blocking call canceled then close, else report error */
if (nWSAerror == WSAEINTR) {
bl_close(hInst, hwnd);
} else {
bl_close(hInst, hwnd);
WSAperror(nWSAerror, "recv()", hInst);
}
goto r_end;
} else if (wRet == 0) { /* Other side closed socket */
MessageBox (hwnd, achOutBuf,
"server closed connection", MB_OK);
goto r_end;;
} else {
/* tally amount received */
cbInLen += wRet;
stWSAppData.lBytesIn += wRet;
}
} /* end recv() loop */
} /* 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_CONNECTED;
/*-------------------------------------*/
/* get timers for statistics updates & I/O (if requested) */
get_timers(hInst, hwnd);
}
r_end:
/* Tell ourselves to do it again (if we're not
* using a timer and we're still connected)! */
if (!stWSAppData.nWinTimer &&
(stWSAppData.nSockState == STATE_CONNECTED))
PostMessage(hwnd, WM_COMMAND, IDM_READ, 0L);
return (cbInLen);
} /* end bl_r() */
/*---------------------------------------------------------------------------
* Function: bl_w()
*
* Description:
* Blocking write
*/
int bl_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 blocking call canceled then close, else report error */
if (nWSAerror == WSAEINTR) {
bl_close(hInst, hwnd);
} else {
bl_close(hInst, hwnd);
WSAperror(nWSAerror, "send()", hInst);
}
goto w_end;
} else {
/* Tally amount sent */
cbOutLen += wRet;
stWSAppData.lBytesOut += wRet;
}
} /* end send() loop */
} /* end main loop */
w_end:
/* Tell ourselves to do it again (if we're not
* using a timer and we're still connected)! */
if (!stWSAppData.nWinTimer &&
(stWSAppData.nSockState == STATE_CONNECTED))
PostMessage(hwnd, WM_COMMAND, IDM_WRITE, 0L);
return (cbOutLen);
} /* end bl_w() */
/*---------------------------------------------------------------------------
* Function: bl_close()
*
* Description:
* Differences between this and a non-blocking close is that this cannot
* handle an WSAEWOULDBLOCK error gracefully (i.e. ignore it ), and this
* will* handle WSAEINPROGRESS gracefully.
*/
int bl_close (HANDLE hInst, HANDLE hwnd)
{
int wRet=0;
/* we may have already set this state earlier,
* but not in all cases */
/*-----------------------------------------*/
stWSAppData.nSockState = STATE_CLOSE_PENDING;
/*-----------------------------------------*/
if (WSAIsBlocking()) {
/* Cancel pending blocking operation before we try to close
* (which would just fail with WSAEINPROGRESS). When the
* pending blocking operation fails with WSAEINTR it will
* call bl_close() and close then close will proceed */
WSACancelBlockingCall();
} else {
/* Doing a close without calling shutdown(how=1), and looping on
* recv() first--the way we do in CloseConn() in WinSockX.lib--
* is dangerous and not robust ...but we're experimenting here */
wRet = closesocket(stWSAppData.nSock);
if (wRet == SOCKET_ERROR) {
if (IsWindow(hwnd)) {
WSAperror(WSAGetLastError(), "closesocket()", hInst);
}
}
/* Socket is invalid now (if it wasn't already) */
/*---------------------------------*/
stWSAppData.nSockState = STATE_NONE;
/*---------------------------------*/
/* free the timer resource(s) (if Window not destroyed yet) */
if (IsWindow (hwnd)) {
KillTimer (hwnd, STATS_TIMER_ID);
if (stWSAppData.nWinTimer)
KillTimer (hwnd, APP_TIMER_ID);
}
} /* end else */
return (wRet);
} /* end bl_close() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -