【发布时间】:2013-01-02 13:43:16
【问题描述】:
代码优先
DWORD WINAPI tcp_t(LPVOID lpParam)
{
SOCKET tcp_client_s = (SOCKET)lpParam;
struct sockaddr_in tcp_client;
int tcp_client_len = sizeof(tcp_client), length;
char req[4096], resp[4096];
getpeername(tcp_client_s, (struct sockaddr *)&tcp_client, &tcp_client_len);
cli_log(PROTO_TCP, LOG_SYS, "(%s:%d) TCP thread spawned\n", inet_ntoa(tcp_client.sin_addr), ntohs(tcp_client.sin_port));
length = get_req_tcp(tcp_client_s, req, tcp_client);
if(strci(req, "GET /syachi2ds/web/", 0))
{
while(!strstr(req, "Connection: close\r\n\r\n"))
length += get_req_tcp(tcp_client_s, req + length, tcp_client);
length = check_req(req, resp);
if(length > 0)
send_resp_tcp(tcp_client_s, resp, length, tcp_client);
}
closesocket(tcp_client_s);
cli_log(PROTO_TCP, LOG_SYS, "(%s:%d) socket closed, closing thread\n", inet_ntoa(tcp_client.sin_addr), ntohs(tcp_client.sin_port));
ExitThread(0);
}
int get_req_tcp(SOCKET in_s, char *buf, struct sockaddr_in in)
{
int retval;
cli_log(PROTO_TCP, LOG_COMM, "(%s:%d) waiting for incoming request...\n", inet_ntoa(in.sin_addr), ntohs(in.sin_port));
if ( (retval = recv(in_s, buf, 4096, 0)) == SOCKET_ERROR)
cli_log(PROTO_TCP, LOG_ERROR, "(%d) recv() failed\n", WSAGetLastError());
cli_log(PROTO_TCP, LOG_COMM, "(%s:%d) data received\n", inet_ntoa(in.sin_addr), ntohs(in.sin_port));
return retval;
}
这是我正在编写的一个更大程序的一部分,该程序执行某种服务器仿真。它适用于未拆分为多个数据包的 TCP 流,否则它会在 while 循环中调用的第一个后续 recv() 上给出 winsock 错误 10014。
PS:strci() 是自定义的不区分大小写的strstr()
PS2:我知道没有检查 req 数组上的缓冲区溢出。
【问题讨论】:
-
如果失败:第一个
get_req_tcp()调用(在循环之前)为length返回哪个值? -
此时 cli_log() 调用 exit(0) 如果 LOG_ERROR 作为第二个参数传递(我已经计划改变这种行为)
-
从socket流中读取的数据不是nul终止的,所以如果你想使用
strstr,你需要在每个recv之后手动添加一个'\0'。