#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define min(a,b) (a)<(b)?(a):(b)
int readline_sock(int sockfd,char* RecvData,int RecvLen)
{
char tmp;
int len = 0;
int ret;
while(len < RecvLen && (ret = recv(sockfd,&tmp,1,0)) == 1)
{
if(tmp == '\r')
break;
memcpy(RecvData + len,&tmp,1);
len += 1;
}
if(ret != 1)
{
printf("readline err %d %s",errno,strerror(errno));
return -1;
}
if(len == RecvLen)
return len;
if(tmp == '\r')
{
ret = recv(sockfd,&tmp,1,0);
if(ret != 1)
{
printf("readline err %d %s",errno,strerror(errno));
return -1;
}
else
{
return len;
}
}
}
int readbytes_sock(int sockfd,char* RecvData,int RecvLen)
{
int len = 0,l = 0;
while((len = recv(sockfd,RecvData + l,RecvLen - l,0)) > 0)
{
l += len;
}
if(len < 0)
return len;
return l;
}
int connect_alipay_new(char *host,int port,char *sendData,int sendData_len,char *recvData,int recvData_maxlen)
{
int sockfd;
struct hostent *phost = NULL;
struct sockaddr_in sin;
char tmp[0x8000 + 1];
int tmp_len = 0;
char name[100],value[100],*index1,*index2;
int fd = 0;
int recv_len = 0 ,len,len2;
printf("gethostbyname start %s\n",__TIME__);
phost = gethostbyname(host);
if(phost ==NULL) return;
sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
printf("gethostbyname end ok %s\n",__TIME__);
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr = *(struct in_addr*)phost->h_addr_list[0];
printf("connect start %s\n",__TIME__);
if(connect(sockfd,(struct sockaddr*)&sin,sizeof(sin)) < 0)
{
printf("connect err [%d] [%s]\n",errno,strerror(errno));
exit(0);
}
printf("connect end ok %s\n",__TIME__);
send(sockfd,sendData,sendData_len,0);
memset(recvData,0,recvData_maxlen);
memset(tmp,0,sizeof(tmp));
tmp_len = readline_sock(sockfd,tmp,sizeof(tmp));
if(tmp_len == -1) return tmp_len;
if(memcmp(tmp,"HTTP/1.1 200",12) != 0)
{
//recv_len = -1;
//goto finish;
}
do
{
memset(tmp,0,sizeof(tmp));
tmp_len = readline_sock(sockfd,tmp,sizeof(tmp));
printf("lllll[%d][%s]\n",tmp_len,tmp);
if(tmp_len <= 0)break;
memset(name,0,sizeof(name));
memset(value,0,sizeof(value));
index1 = strchr(tmp,':');
if(index == NULL) break;
strncpy(name,tmp,index1 - tmp);
if(*(index1+1) == ' ') index1++;
strcpy(value,index1);
printf("name:[%s] value[%s]\n",name,value);
setenv(name,value,1);
}while(1);
memset(recvData,0,recvData_maxlen);
if(tmp_len < 0)
{
recv_len = -1;
goto finish;
}
fd = open("log2",O_WRONLY|O_CREAT,0664);
index1 = NULL;
index1 = getenv("Transfer-Encoding");
if(index1 != NULL)
{
recv_len = 0;
while(1)
{
memset(tmp,0,sizeof(tmp));
tmp_len = readline_sock(sockfd,tmp,sizeof(tmp));
if(tmp_len == 0)
{
recv_len = -1;
goto finish;
}
len = 0;
sscanf(tmp,"%x",&len);
printf("len:[%d]\ndata:[%s]",len,tmp);
if(len == 0)
{
printf("finish\n");
break;
}
memset(tmp,0,sizeof(tmp));
tmp_len = 0;
tmp_len = readbytes_sock(sockfd,tmp,len);
if(tmp_len != len || tmp_len < 0)
{
printf("tmp_len != len,tmp_len=[%d] len=[%d]\n",tmp_len,len);
recv_len = -1;
goto finish;
}
else
{
write(fd,tmp,len);
//memcpy(recvData + recv_len,tmp,len);
recv_len += len;
}
tmp_len = readline_sock(sockfd,tmp,sizeof(tmp));
if(tmp_len == 0)
continue;
else
break;
}
goto finish;
}
index1 = NULL;
index1 = getenv("Content-Length");
if(index1 != NULL)
{
len = atol(index1);
printf("Content-Lenght[%d]\n",len);
if(len >= recvData_maxlen)
{
recv_len = -1;
goto finish;
}
else
{
recv_len = readbytes_sock(sockfd,recvData,len);
if(recv_len < len)
{
recv_len = -1;
goto finish;
}
goto finish;
}
}
finish:
close(sockfd);
return recv_len;
}
int connect_alipay_fd(char *host,int port,char *sendData,int sendData_len,int fd)
{
int sockfd;
struct hostent *phost = NULL;
struct sockaddr_in sin;
char tmp[0x8000 + 1];
int tmp_len = 0;
char name[100],value[100],*index1,*index2;
int recv_len = 0 ,len,len2;
printf("gethostbyname start %s\n",__TIME__);
phost = gethostbyname(host);
if(phost ==NULL) return;
sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
printf("gethostbyname end ok %s\n",__TIME__);
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr = *(struct in_addr*)phost->h_addr_list[0];
printf("connect start %s\n",__TIME__);
if(connect(sockfd,(struct sockaddr*)&sin,sizeof(sin)) < 0)
{
printf("connect err [%d] [%s]\n",errno,strerror(errno));
exit(0);
}
printf("connect end ok %s\n",__TIME__);
send(sockfd,sendData,sendData_len,0);
memset(tmp,0,sizeof(tmp));
tmp_len = readline_sock(sockfd,tmp,sizeof(tmp));
if(tmp_len == -1) return tmp_len;
if(memcmp(tmp,"HTTP/1.1 200",12) != 0)
{
//recv_len = -1;
//goto finish;
}
do
{
memset(tmp,0,sizeof(tmp));
tmp_len = readline_sock(sockfd,tmp,sizeof(tmp));
printf("lllll[%d][%s]\n",tmp_len,tmp);
if(tmp_len <= 0)break;
memset(name,0,sizeof(name));
memset(value,0,sizeof(value));
index1 = strchr(tmp,':');
if(index == NULL) break;
strncpy(name,tmp,index1 - tmp);
if(*(index1+1) == ' ') index1+=2;
else index1 +=1;
strcpy(value,index1);
printf("name:[%s] value[%s]\n",name,value);
setenv(name,value,1);
}while(1);
if(tmp_len < 0)
{
recv_len = -1;
goto finish;
}
index1 = NULL;
index1 = getenv("Transfer-Encoding");
if(index1 != NULL && strcmp(index1,"chunked") == 0)
{
recv_len = 0;
while(1)
{
memset(tmp,0,sizeof(tmp));
tmp_len = readline_sock(sockfd,tmp,sizeof(tmp));
if(tmp_len == 0)
{
recv_len = -1;
goto finish;
}
len = 0;
sscanf(tmp,"%x",&len);
printf("len:[%d]\ndata:[%s]",len,tmp);
if(len == 0)
{
printf("finish\n");
break;
}
memset(tmp,0,sizeof(tmp));
tmp_len = 0;
tmp_len = readbytes_sock(sockfd,tmp,len);
if(tmp_len != len || tmp_len < 0)
{
printf("tmp_len != len,tmp_len=[%d] len=[%d]\n",tmp_len,len);
recv_len = -1;
goto finish;
}
else
{
write(fd,tmp,len);
}
tmp_len = readline_sock(sockfd,tmp,sizeof(tmp));
if(tmp_len == 0)
continue;
else
break;
}
goto finish;
}
index1 = NULL;
index1 = getenv("Content-Length");
if(index1 != NULL)
{
len = atol(index1);
printf("Content-Lenght[%d]\n",len);
recv_len = 0;
while(recv_len < len)
{
memset(tmp,0,sizeof(tmp));
tmp_len = readbytes_sock(sockfd,tmp,min(len - recv_len,sizeof(tmp)-1));
if(tmp_len < 0)
{
recv_len = -1;
goto finish;
}
recv_len += tmp_len;
write(fd,tmp,tmp_len);
}
goto finish;
}
finish:
close(sockfd);
return recv_len;
}
int main()
{
//char *host = "www.baidu.com";
//int port = 80;
char *host = "127.0.0.1";
int port = 8888;
int fd = open("log",O_WRONLY|O_CREAT|O_TRUNC,0664);
int recv_len,len;
char sendData[40960] = {0},recvData[40960] = {0};
sprintf(sendData,"GET / HTTP/1.1\r\nAccept: */*\r\nAccept-Language: zh-Hans-CN, zh-Hans; q=0.8, en-US; q=0.5, en; q=0.3\r\nConnection: close\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134\r\n\r\n",host);
//recv_len = connect_alipay_new(host,port,sendData,strlen(sendData),recvData,sizeof(recvData));
recv_len = connect_alipay_fd(host,port,sendData,strlen(sendData),fd);
close(fd);
return;
}
部分代码参考自tinyhttpd https://github.com/EZLippi/Tinyhttpd
下面是用tornado实现的服务端,以分段传输Transfer-Encoding: chunked返回
import tornado
import tornado.web
import os
import socket
import multiprocessing
import time
port = 8888
class IndexHandler(tornado.web.RequestHandler):
def get(self):
for i in range(100):
self.write('A'*0x8000)
self.flush()
def main():
sockets = tornado.netutil.bind_sockets(port,family = socket.AF_INET)
app = tornado.web.Application([(r"/", IndexHandler,),])
httpd = tornado.httpserver.HTTPServer(app)
httpd.add_sockets(sockets)
tornado.ioloop.IOLoop.current().start()
if __name__ == '__main__':
main()