小弟的一个socket问题
http://topic.csdn.net/u/20071225/08/fdd06714-9e16-4266-9d40-69d3ffceb2a3.html
遇到了相同的问题, 有经验的朋友帮个忙,先谢谢了
附注:
这段代码在VC下是能够正常执行的, 但是C++ Builder就是不行;
去掉setsockopt也能正常Bind,但必须要设置。
原问题如下:
C/C++ code
WSADATA WSAData;
BOOL flag = true;
int nTimeOut =1000;
char LocalName[16];
SOCKADDR_IN addr_in;
struct hostent *pHost;
// const int BUFFER_SIZE =100;
SOCKET sock;
char RecvBuf[BUFFER_SIZE];
if(WSAStartup(MAKEWORD(2,2),&WSAData)!=0)return ;
if((sock=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))==INVALID_SOCKET)return ;
if(gethostname((char*)LocalName,sizeof(LocalName))==SOCKET_ERROR)return ;
if((pHost=gethostbyname((char*)LocalName))==NULL)return ;
addr_in.sin_addr = *(in_addr *)pHost->h_addr_list[0];
addr_in.sin_family = AF_INET;
addr_in.sin_port = htons(31);
if(setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char *)&flag,sizeof(flag))==SOCKET_ERROR)return ;
if(bind(sock,(PSOCKADDR)&addr_in,sizeof(addr_in))==SOCKET_ERROR)
{
int iTmp=WSAGetLastError();
return;
}
上面是部分源码,如果直接编译 那么就会在bind函数处出错 错误代码10049 提示地址出错。
但是 如果把 if(setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char *)&flag,sizeof(flag))==SOCKET_ERROR)return ;这一行去掉, 就可以正常bind。问题是由于我要去解析IP协议,所以不能省,请教各位兄弟,该如何解决?
[解决办法]
使用bcb中的控件吧
[解决办法]
int PASCAL FAR setsockopt( SOCKET s, int level, int optname,
const char FAR* optval, int optlen);
s:标识一个套接口的描述字。
level:选项定义的层次;目前仅支持SOL_SOCKET和IPPROTO_TCP层次。
optname:需设置的选项。
optval:指针,指向存放选项值的缓冲区。
optlen:optval缓冲区的长度。
注释:
setsockopt()函数用于任意类型、任意状态套接口的设置选项值。尽管在不同协议层上存在选项,但本函数仅定义了最高的“套接口”层次上的选项。选项影响套接口的操作,诸如加急数据是否在普通数据流中接收,广播数据是否可以从套接口发送等等。
有两种套接口的选项:一种是布尔型选项,允许或禁止一种特性;另一种是整形或结构选项。允许一个布尔型选项,则将optval指向非零整形数;禁止一个选项optval指向一个等于零的整形数。对于布尔型选项,optlen应等于sizeof(int);对其他选项,optval指向包含所需选项的整形数或结构,而optlen则为整形数或结构的长度。SO_LINGER选项用于控制下述情况的行动:套接口上有排队的待发送数据,且closesocket()调用已执行。参见closesocket()函数中关于SO_LINGER选项对closesocket()语义的影响。应用程序通过创建一个linger结构来设置相应的操作特性:
struct linger {
int l_onoff;
int l_linger;
};
为了允许SO_LINGER,应用程序应将l_onoff设为非零,将l_linger设为零或需要的超时值(以秒为单位),然后调用setsockopt()。为了允许SO_DONTLINGER(亦即禁止SO_LINGER),l_onoff应设为零,然后调用setsockopt()。
缺省条件下,一个套接口不能与一个已在使用中的本地地址捆绑(参见bind())。但有时会需要“重用”地址。因为每一个连接都由本地地址和远端地址的组合唯一确定,所以只要远端地址不同,两个套接口与一个地址捆绑并无大碍。为了通知WINDOWS套接口实现不要因为一个地址已被一个套接口使用就不让它与另一个套接口捆绑,应用程序可在bind()调用前先设置SO_REUSEADDR选项。请注意仅在bind()调用时该选项才被解释;故此无需(但也无害)将一个不会共用地址的套接口设置该选项,或者在bind()对这个或其他套接口无影响情况下设置或清除这一选项。
我个人认为:
if(setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char *)&flag,sizeof(flag))==SOCKET_ERROR)return;
在bind前没有意义
[解决办法]
我也遇到过这样的问题,查过一些资料说是参数传递的问题。
[解决办法]
如果在XP以上的操作系统,微软封杀了Raw Soccket!