百分求教:怎样用socket接收http请求,解析Http包头,获取content-length的值??
如题,用Socket侦听客户请求,接受Http请求,怎样才可以先获取Http包头,解析得到content-length,然后根据content-length,接收Http body,那位有解决之道??? 问题点数:100、回复次数:18Top
1 楼chsfly(一蓑烟雨任平生)回复于 2005-02-01 12:13:54 得分 10
http://www.chinaitlab.com/www/news/article_show.asp?id=22299Top
2 楼yes4pierce(pierce)回复于 2005-02-01 12:35:36 得分 0
那篇文章看了,没有太大帮助,用Socket.Receive()接收数据,如果用固定长度数组接收,byte[] bs=new byte[1024],实际应用中会产生问题,如果实际一条数据不足1024个字节,那么后续接收到的数据会同第一条数据一起被读取,如第一条信息是hello,第2条是world,那么收到的信息就是helloworld,同样,处理Http请求,如果只接收Http header,用固定长度数组的话,会收到http body的信息,为了防止这种情况,需要获取http header的content-length值,根据这个值,才可以确保正确接收http body的信息,现在探求获取http header中content-length的实现方式,即http 协议的实现方式。Top
3 楼stonegoldaustin(特醇中南海)回复于 2005-02-01 12:35:52 得分 10
if(m_socket.Connected)
{
string msg = "GET / HTTP/1.1\r\nHost: " + txt_Address.Text + "\r\nConnection:Close\r\n\r\n";
m_socket.Send(System.Text.Encoding.ASCII.GetBytes(msg));
ReceiveData();
}Top
4 楼trnbo(【没有蛀牙】)回复于 2005-02-01 13:01:58 得分 0
楼主是要做服务器端开发吗?Top
5 楼haoco()回复于 2005-02-01 13:15:55 得分 0
upTop
6 楼sun926(初学者)回复于 2005-02-01 13:26:47 得分 0
直接使用HttpWebRequest和HttpWebResponse就可以了。Top
7 楼chsfly(一蓑烟雨任平生)回复于 2005-02-01 13:28:25 得分 10
是不是可能通过字符串索引找出content-length关键字然后取出其值.Top
8 楼yes4pierce(pierce)回复于 2005-02-01 13:35:38 得分 0
如果用httpWebRequest和HttpWebResponse 当然可以了,只是面临的问题是要用Socket,Socket通讯是非常严谨的,否则会出现意想不到的问题,我们使用高级协议如Http,也是用Socket 实现的,只是不知道是怎样实现的这种高级功能,虽然不是全部实现,但是想找到办法。
目前实现了一个低效率的方法,即有请求,用Socket.Receive()方法,每次读一个字节,用StingBuilder累加成字符串,找到http header 和http body的分隔符,然后解析http Header,测试可以用,只是效率太低,看看大家有没有好的解决办法。Top
9 楼htren(糊涂)回复于 2005-02-02 09:02:56 得分 20
BOOL CGenericServer::IsComplete(CString szRequest)
{
//////////////////////////
//功能:判断是否读完HTTP请求
//参数:szRequest 包内容
//返回值:TRUE 完成接收
//////////////////////////
CString szMethod;
//找到第一空格
int n = szRequest.Find(_T(" "), 0);
if(n != -1)
{
//取空格前几个字符
szMethod = szRequest.Left(n);
//判断发送格式 GET or POST
if(szMethod.Compare(_T("GET"))==0)
{
//获取最后几位是否为\r\n\r\n
if (szRequest.Right(4).Compare(_T("\r\n\r\n"))==0)
{
szMethod.ReleaseBuffer();
return TRUE;
}
else
{
return FALSE;
}
}
if(szMethod.Compare(_T("POST"))==0)
{
//查找参数
n = szRequest.Find(_T("Content-Length:"), 0);
if (n==-1)
{
szMethod.ReleaseBuffer();
return FALSE;
}
//取"Content-Length:"后的字符串,并取出参数字节数
szMethod=szRequest.Right(szRequest.GetLength()-n);
n = szMethod.Find(_T(":"), 0);
if (n==-1)
{
szMethod.ReleaseBuffer();
return FALSE;
}
szMethod=szMethod.Right(szMethod.GetLength()-n-1);
n= szMethod.Find(_T("\r\n"), 0);
if (n==-1)
{
szMethod.ReleaseBuffer();
return FALSE;
}
szMethod=szMethod.Left(n);
szMethod.TrimLeft();
//取出字节数
int len=_ttoi(szMethod);
//查找参数前的\r\n\r\n
n=szRequest.Find(_T("\r\n\r\n"),0);
if (n==-1)
{
szMethod.ReleaseBuffer();
return FALSE;
}
//取得当前读到的参数长度
int datalen=szRequest.GetLength()-n-4;
if (datalen>=len)
{
szMethod.ReleaseBuffer();
return TRUE;
}
else
{
szMethod.ReleaseBuffer();
return FALSE;
}
}
}
else
return FALSE;
return FALSE;
}
Top
10 楼htren(糊涂)回复于 2005-02-02 09:05:57 得分 20
DWORD NumberOfBytesRecvd;
WSABUF Buffers;
DWORD dwBufferCount = 1;
char szBuffer[MAX_BUFFER];
DWORD Flags = 0;
Buffers.buf = szBuffer;
Buffers.len = MAX_BUFFER;
result = WSARecv(
s,
&Buffers,
dwBufferCount,
&NumberOfBytesRecvd,
&Flags,
NULL,
NULL);
if(result != SOCKET_ERROR)
{
//
// Chech if we got complete request
//
szRequest += CString(szBuffer);
memset(szBuffer,0,MAX_BUFFER);
//判断是否已全部收到
if(!pGenericServer->IsComplete(szRequest))
{
if (szRequest.GetLength()>2046)
{
szRequest.ReleaseBuffer();
szResponse.ReleaseBuffer();
pGenericServer->CleanupThread(Event, s, NULL,NULL);
return THREADEXIT_SUCCESS;
}
else
{
continue;
}
}
}
用EVC写的Top
11 楼mooddecode1980(心情解码)回复于 2005-02-02 09:08:16 得分 0
第十个
upTop
12 楼yes4pierce(pierce)回复于 2005-02-02 11:55:57 得分 0
CString szRequest,是收到的字符,对吧?
但是怎样完整的收到请求,而不会多收取信息或者少收取信息呢?
如果请求时Get,那么Client发送完请求后,要等待回复,Client发送完请求后,没有其他特殊标示的,Server只能根据TcpBuffer收到的信息作处理,TcpBuffer中既有Http header的信息,也有Http body的信息,如果只读取http header的话,有没有好的方法???
如果只有一个Client请求的话,用固定长度字节数组读取也没有问题,但是有多个Client请求,或者一个Client作并发请求,那么用固定长度字节数组接收会有问题,读取Header,根据content-length读取Body就很重要了。Top
13 楼amendajing(学习,是个漫长的旅途!)回复于 2005-02-02 12:27:00 得分 0
markTop
14 楼chsfly(一蓑烟雨任平生)回复于 2005-02-04 09:29:56 得分 0
关注到现在楼主是不是要开发一个web服务器呀?Top
15 楼singleflower(诗凡(愿父亲安息))回复于 2005-02-04 09:43:39 得分 10
关注Top
16 楼xiaowang_net(小王)回复于 2005-02-04 10:07:55 得分 10
是不是要做web服务器?Top
17 楼yes4pierce(pierce)回复于 2005-02-11 19:00:04 得分 0
倒不是要做web服务器,只是想知道一些协议和方法的实现方式,如http协议,stream的Readline() 方法Top
18 楼nga96(因为我笨,所以努力。陈勇华)回复于 2005-02-13 20:34:58 得分 10
自己写比较烦人的,也是最可靠的Top




