問(wèn)題的引出
在計(jì)算機(jī)程序中,除了常見的執(zhí)行流程控制,還有邏輯流程控制;有時(shí),執(zhí)行流程即為邏輯流程,但在大多數(shù)情況下還是有所區(qū)別的,例如,假定有一個(gè)Web服務(wù)器使用同步套接字讀取HTTP請(qǐng)求,那么會(huì)編寫如下的代碼:
void read(HTTP_REQUEST& http_request)
{
read(http_request.header);
read(http_request.body, http_request.header);
}
void read(HTTP_REQUEST_HEADER& header)
{
string line = read_line();
parse_request_link(line, header.method, header.uri,
header.version);
while (TRUE)
{
line = read_line();
if (line.empty())
break;
parse_header_field(line, header);
}
}
void read(BYTE[]& body, HTTP_REQUEST_HEADER& header)
{
string transfer_encoding = header.fields['Transfer-Encoding'];
if (transfer_encoding != b.chunkedb.)
body = read_bytes(header.fields['Content-Length']);
else
{
while (TRUE)
{
string chunk_header = read_line();
DWORD chunk_size = atoi(chunk_header);
if (chunk_size == 0)
break;
BYTE[] chunk_body = read_bytes(chunk_size);
body += chunk_body;
}
}
}
string read_line()
{
while (TRUE)
{
int n = strpos(read_buffer, b.\nb., read_buffer.size());
if (n > 0)
break;
read_buffer += socket.read();
}
return read_buffer.extract(n);
}
Byte[] read_bytes(int sz)
{
while (TRUE)
{
if (sz <= read_buffer.size())
break;
read_buffer += socket.read();
}
return read_buffer.extract(sz);
}
在這段代碼中,執(zhí)行流程與邏輯流程是一致的,然而,如果在那些被動(dòng)接收事件的場(chǎng)合使用了異步套接字,就必須編寫下面這樣的代碼了:
read()
{
read_buffer += socket.read();
if (state == read_request_line)
{
if (!read_line(line))
return;
parse_request_link(line, method, uri, version);
state = read_header_field;
}
while (state == read_request_line)
{
if (!read_line(line))
return;
if (line.empty())
{
transfer_encoding = header.fields['Transfer-Encoding'];
if (transfer_encoding != b.chunkedb.)
{
content_length = header.fields['Content-Length'];
state = read_body;
}
else
state = read_chunk_header;
}
else
parse_header_field(line, header, value);
}
if (state == read_body)
{
request_body += read_buffer;
read_buffer.clear();
if (request_body.size() >= content_length)
state = read_finished;
return;
}
if (state == read_chunk_header)
{
if (!read_line(line))
return;
chunk_size = atoi(line);
if (chunk_size == 0)
{
state = read_finished;
return;
}
state = read_body;
}
if (state == read_chunk_body)
{
request_body.append(read_buffer, chunk_size);
if (chunk_size == 0)
state = read_chunk_header;
return;
}
}
執(zhí)行流程完全不同了,但邏輯流程卻仍保持不變,因?yàn)橹荒芤粔K一塊地接收數(shù)據(jù),還必須保存狀態(tài)值及其他變量,以便在事件發(fā)生時(shí)進(jìn)行相應(yīng)的處理。以上只是一些示范性代碼,并不能真正工作,在實(shí)際中要編寫像這樣的函數(shù)會(huì)更加復(fù)雜,也更加容易出錯(cuò)
在計(jì)算機(jī)程序中,除了常見的執(zhí)行流程控制,還有邏輯流程控制;有時(shí),執(zhí)行流程即為邏輯流程,但在大多數(shù)情況下還是有所區(qū)別的,例如,假定有一個(gè)Web服務(wù)器使用同步套接字讀取HTTP請(qǐng)求,那么會(huì)編寫如下的代碼:
void read(HTTP_REQUEST& http_request)
{
read(http_request.header);
read(http_request.body, http_request.header);
}
void read(HTTP_REQUEST_HEADER& header)
{
string line = read_line();
parse_request_link(line, header.method, header.uri,
header.version);
while (TRUE)
{
line = read_line();
if (line.empty())
break;
parse_header_field(line, header);
}
}
void read(BYTE[]& body, HTTP_REQUEST_HEADER& header)
{
string transfer_encoding = header.fields['Transfer-Encoding'];
if (transfer_encoding != b.chunkedb.)
body = read_bytes(header.fields['Content-Length']);
else
{
while (TRUE)
{
string chunk_header = read_line();
DWORD chunk_size = atoi(chunk_header);
if (chunk_size == 0)
break;
BYTE[] chunk_body = read_bytes(chunk_size);
body += chunk_body;
}
}
}
string read_line()
{
while (TRUE)
{
int n = strpos(read_buffer, b.\nb., read_buffer.size());
if (n > 0)
break;
read_buffer += socket.read();
}
return read_buffer.extract(n);
}
Byte[] read_bytes(int sz)
{
while (TRUE)
{
if (sz <= read_buffer.size())
break;
read_buffer += socket.read();
}
return read_buffer.extract(sz);
}
在這段代碼中,執(zhí)行流程與邏輯流程是一致的,然而,如果在那些被動(dòng)接收事件的場(chǎng)合使用了異步套接字,就必須編寫下面這樣的代碼了:
read()
{
read_buffer += socket.read();
if (state == read_request_line)
{
if (!read_line(line))
return;
parse_request_link(line, method, uri, version);
state = read_header_field;
}
while (state == read_request_line)
{
if (!read_line(line))
return;
if (line.empty())
{
transfer_encoding = header.fields['Transfer-Encoding'];
if (transfer_encoding != b.chunkedb.)
{
content_length = header.fields['Content-Length'];
state = read_body;
}
else
state = read_chunk_header;
}
else
parse_header_field(line, header, value);
}
if (state == read_body)
{
request_body += read_buffer;
read_buffer.clear();
if (request_body.size() >= content_length)
state = read_finished;
return;
}
if (state == read_chunk_header)
{
if (!read_line(line))
return;
chunk_size = atoi(line);
if (chunk_size == 0)
{
state = read_finished;
return;
}
state = read_body;
}
if (state == read_chunk_body)
{
request_body.append(read_buffer, chunk_size);
if (chunk_size == 0)
state = read_chunk_header;
return;
}
}
執(zhí)行流程完全不同了,但邏輯流程卻仍保持不變,因?yàn)橹荒芤粔K一塊地接收數(shù)據(jù),還必須保存狀態(tài)值及其他變量,以便在事件發(fā)生時(shí)進(jìn)行相應(yīng)的處理。以上只是一些示范性代碼,并不能真正工作,在實(shí)際中要編寫像這樣的函數(shù)會(huì)更加復(fù)雜,也更加容易出錯(cuò)

