原始套接字接收时犯的一个错误

if ( (nread = recvfrom( fd, ptr, nleft, 0, (sockaddr*)&m_addrSourceIp,
				                    &sizeSock) ) < 0)




int CSynScan::CheckSyn(const char* _buffPackage)
{
	assert( _buffPackage!=NULL);

	cout<<"pTcp->tcp_flags:"<<pTcp->tcp_flags<<endl;
	cout<<"pTcp->acknowledgement:"<<ntohl(pTcp->tcp_acknowledgement)<<endl;
  cout<<"pTcp->ack:"<<ntohl(pTcp->tcp_ack)<<endl;


这就是我的接收语句和处理过程,一开始,我总是接收到不是我所期待的值。又很仔细的将程序检查了一遍,用tcpdump抓包(包收发均正常)逐个排查后,对sockaddr_in这个结构体起了疑心。可是又一时说不出问题在哪儿。 后来我自己问了自己一个问题, 套接字怎么知道在哪个端口接哪个数据?TCP上,服务端可以bind,客户端connect。UDP上,sendto有个sockaddr_in结构体参数,指示它进行发送,recvfrom的sockaddr_in结构存储了收到时的对方主机地址参数等。 等等,我似乎遗漏了什么,recvfrom依据什么来让套接字明白从哪个端口接收? bind?对,就是它,recvfrom需要一个bind。原始套接字能否进行bind还得实验下,但是在扫描程序里,套接字通常不去绑定一个端口进行发送,而是随机的指定,这样才能加快扫描的速度。。。
    恩,既然这样,那么在没有bind的情况下,recvfrom似乎是接到了所有进程的数据。那么我又在处理程序里加上了这句

	if( (ntohl(pTcp->tcp_ack)!=SEQ_TCP+1) )
		{
			cout<<"xx"<<endl;
		 return -1;	
		}


OK.搞定。那么recv程序根据是否接到正确的包进行重复的接收,直接收到正确的包。如果超时,你还可以设定个标志,如果N秒内没有改变它,就判定它超时吧 ^_^

你可能感兴趣的:(java)