void* yang_run_http_thread(void *obj){
char* buf=(char*)calloc(Yang_Http_Buffer,1);
char* rets=(char*)calloc(1024*16,1);
char* answer=(char*)calloc(1024*16,1);
char* tmp=NULL;
//从p2pServer中取出socket读写标识和客户端ip地址
YangP2pServer* p2p=(YangP2pServer*)obj;
int connfd=p2p->connFd;
char remoteIp[32]={0};
strcpy(remoteIp,p2p->remoteIp);
int32_t nBytes =0;
int32_t recvLen = 0;
int32_t recvtimes=0;
int32_t contentLen=0;
char contentLenStr[20];
int32_t contetSize=sizeof(Yang_Http_Content);
char* p=NULL;
int32_t headerLen=0;
while (true) {
//重置httpbuf中的内容,然后调用recv方法从sokcet中读取buf大小的内容。
memset(buf, 0, Yang_Http_Buffer);
nBytes = recv(connfd, (char*) buf, Yang_Http_Buffer, 0);
if (nBytes > 0) {
//如果socket中读到了内容,则将其复制到rets中。
memcpy(rets + recvLen, buf, nBytes);
//recvLen记入读取长度。
recvLen += nBytes;
//如果首次接收buf中不包含HTTP子串,则不处理。
if(recvtimes==0&&strstr(buf, "HTTP")==NULL) break;
//记录接收次数
recvtimes++;
if(headerLen==0){
//查找\r\n\r\n计算header的长度
char* headerp=strstr(rets,"\r\n\r\n");
if(headerp==NULL) continue;
if (headerp) {
int32_t contentPos = headerp - rets;
if (contentPos > 0) headerLen = contentPos + 4;
}
//在rets中查找Content-Length:
p=strstr(rets,Yang_Http_Content);
if(p&&headerp-p>0){
//查找Content-Length:之后的第一个\r的index
int32_t ind=yang_cstr_userfindindex(p,'\r');
//判断Content-Length:之后是否有内容。
if(ind>contetSize){
//重置contenLenStr,然后从p中读取放到contenLenStr中。
memset(contentLenStr,0,sizeof(contentLenStr));
memcpy(contentLenStr,p+contetSize,ind-contetSize);
//从contentLenStr中读取首个数字在Str中的下标
int numberIndex=yang_cstr_isnumber(contentLenStr,sizeof(contentLenStr));
if(numberIndex>-1&&numberIndex<sizeof(contentLenStr)){
//如果在contentLenStr中能找到数字,则调用atoi转为int类型放到contentLen中。
contentLen=atoi(contentLenStr+numberIndex);
}
}
}
}
//如果contentLen有内容,并且recvLen读取长度大于等于headerLen+contentLen,则跳转成功。
if(contentLen>0&&recvLen >= headerLen+contentLen) goto success;
//如果contentLen没有内容并且headerLen有内容且buf中包含},则跳转成功。
if(contentLen==0&&headerLen>0&&strstr(buf,"}")) goto success;
continue;
} else if (nBytes == -1) {
//没有读到数据,则获取sockError,部分error continue,其他error直接break。
int32_t sockerr = GetSockError();
if (sockerr == EINTR)
continue;
if (sockerr == EWOULDBLOCK || sockerr == EAGAIN) {
nBytes = 0;
continue;
}
yang_error("%s, recv returned %d. GetSockError(): %d (%s)",
__FUNCTION__, nBytes, sockerr, strerror(sockerr));
break;
} else if (nBytes == 0) {
//nBtyes为0说明已经读完了所有内容,直接break。
break;
}
break;
}
//关闭socket
closesocket(connfd);
yang_free(buf);
yang_free(rets);
yang_free(answer);
return NULL;
//成功需要做的操作。
success:
//将header之后body中的\r\n替换为\n后将body放入tmp中。
if(tmp==NULL) tmp=(char*)calloc(1024*16,1);
yang_cstr_replace(rets+headerLen, tmp, "\r\n","\n");
//重置rets中的内容
memset(rets,0,1024*16);
//将tmp中的}去掉,然后放到rets中。
yang_cstr_replace(tmp,rets,"}","");
//调用p2pServer的receive方法将接收数据传入,然后拿到answer。
p2p->receive(rets, strlen(rets)+1, answer,remoteIp,p2p->user);
//将answer通过socket的连接标识发送除去。
nBytes = send(connfd, answer, strlen(answer), 0);
//sleep 1秒。
yang_sleep(1);
//关闭与客户端的socket连接
closesocket(connfd);
yang_free(tmp);
yang_free(buf);
yang_free(rets);
yang_free(answer);
return NULL;
}
metartc5_jz源码阅读-yang_run_http_thread
于 2023-12-30 19:02:46 首次发布