SOCKET编程中遇到的问题

runningdog_1 2008-10-06 03:44:23
有一种这样的需求:本机有N(N>1)个IP地址,创建一个不绑定任何一个IP地址的套接字。现在想在收到数据包后获得该数据包是发给本机的哪个IP地址的。

请问要怎么做。
...全文
208 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
Arthur_ 2008-10-07
  • 打赏
  • 举报
回复
搞得如此麻烦, 用SOCK_RAW 就可以吧 可以将L3的头传上来。
runningdog_1 2008-10-06
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 mengge 的回复:]
TCP确实可以通过具体的socket句柄来执行相应的操作来获取具体的IP地址信息。
但是UDP比较麻烦,貌似只有从TCP协议上下手,但是对于应用层来说,取到数据时已经过了协议层 :D
所以,除非在应用层数据上写明地址信息。
[/Quote]
好像看到过用 ioctl实现方法一样,现在找不到了。。。~~~~~
baihacker 2008-10-06
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 runningdog_1 的回复:]
不好意思,没太明白。

普通的套接字(非raw socket)可以由用户指定ip头的信息吗?另外,“考虑底层的协议”的具体含义是?
[/Quote]
你应该考虑你是利用哪一层的服务编程.
你这里貌似就是指利用传输层中的UDP协议进行编程吧.
那么你所看到的只是收到的数据.
于是你就需要客户发送的数据中用一个域保存客户端的地地址和端口.

如果是再底层的话,你就可以看到源和目的的东西了.

踏岸寻柳 2008-10-06
  • 打赏
  • 举报
回复
TCP确实可以通过具体的socket句柄来执行相应的操作来获取具体的IP地址信息。
但是UDP比较麻烦,貌似只有从TCP协议上下手,但是对于应用层来说,取到数据时已经过了协议层 :D
所以,除非在应用层数据上写明地址信息。
runningdog_1 2008-10-06
  • 打赏
  • 举报
回复
不好意思,没太明白。

普通的套接字(非raw socket)可以由用户指定ip头的信息吗?另外,“考虑底层的协议”的具体含义是?
baihacker 2008-10-06
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 runningdog_1 的回复:]
引用 11 楼 baihacker 的回复:
引用 9 楼 runningdog_1 的回复:
谢谢“飞雪”

现在需求进一步:在楼顶所提到的情况的基础上,应用程序要如何才能确保自己构造的回复数据包在发送到链路上后,包中的源地址是请求包发过来的地址(即对方使用的目的地址)

确定一个连接需要两个IP两个port.既然连接都建立了,还有问题吗?

UDP的情况呢?
[/Quote]
考虑底层的协议或者让用户在数据中写上自己的地址.
runningdog_1 2008-10-06
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 baihacker 的回复:]
引用 9 楼 runningdog_1 的回复:
谢谢“飞雪”

现在需求进一步:在楼顶所提到的情况的基础上,应用程序要如何才能确保自己构造的回复数据包在发送到链路上后,包中的源地址是请求包发过来的地址(即对方使用的目的地址)

确定一个连接需要两个IP两个port.既然连接都建立了,还有问题吗?
[/Quote]
UDP的情况呢?
runningdog_1 2008-10-06
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 runningdog_1 的回复:]
8楼据所说的是TCP的情况,UDP是怎样的呢?
[/Quote]
UDP的情况呢?
runningdog_1 2008-10-06
  • 打赏
  • 举报
回复
这种需求在实际情况中会变得十分有用,尤其是基于UDP的应用。例如 DNS,RFC1035中提到

7.3. Processing responses
....
- Some name servers send their responses from different
addresses than the one used to receive the query. That is, a
resolver cannot rely that a response will come from the same
address which it sent the corresponding query to. This name
server bug is typically encountered in UNIX systems.

这意味着一个DNS client的标准实现将会接收非合法的DNS服务器的回复,dns reply spoof就这样发生了,域名劫持就这样发生了。

这还只是影响一个客户端,如若发起查询请求的是一台dns缓存服务器呢,那问题就大了。
baihacker 2008-10-06
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 runningdog_1 的回复:]
谢谢“飞雪”

现在需求进一步:在楼顶所提到的情况的基础上,应用程序要如何才能确保自己构造的回复数据包在发送到链路上后,包中的源地址是请求包发过来的地址(即对方使用的目的地址)
[/Quote]
确定一个连接需要两个IP两个port.既然连接都建立了,还有问题吗?
runningdog_1 2008-10-06
  • 打赏
  • 举报
回复
8楼据所说的是TCP的情况,UDP是怎样的呢?
runningdog_1 2008-10-06
  • 打赏
  • 举报
回复
谢谢“飞雪”

现在需求进一步:在楼顶所提到的情况的基础上,应用程序要如何才能确保自己构造的回复数据包在发送到链路上后,包中的源地址是请求包发过来的地址(即对方使用的目的地址)
jingtan 2008-10-06
  • 打赏
  • 举报
回复
楼主, 是这样的.你用于bind和listen的socket是不指定本机ip的,绑定时用ADDR_ANY作为地址参数.
然后当你accept一个连接后会得到一个新的socket. 这样你就可以把新的 socket传送给getsockname 函数,取得这个连接对应的地址了.
baihacker 2008-10-06
  • 打赏
  • 举报
回复
getpeername Function

The getpeername function retrieves the address of the peer to which a socket is connected.


int getpeername(
__in SOCKET s,
__out struct sockaddr* name,
__in_out int* namelen
);

Parameters
s
A descriptor identifying a connected socket.

name
The SOCKADDR structure that receives the address of the peer.

namelen
A pointer to the size, in bytes, of the name parameter.

Return Value
If no error occurs, getpeername returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error code Meaning
WSANOTINITIALISED
A successful WSAStartup call must occur before using this function.

WSAENETDOWN
The network subsystem has failed.

WSAEFAULT
The name or the namelen parameter is not in a valid part of the user address space, or the namelen parameter is too small.

WSAEINPROGRESS
A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.

WSAENOTCONN
The socket is not connected.

WSAENOTSOCK
The descriptor is not a socket.


Remarks
The getpeername function retrieves the address of the peer connected to the socket s and stores the address in the SOCKADDR structure identified by the name parameter. This function works with any address family and it simply returns the address to which the socket is connected. The getpeername function can be used only on a connected socket.

For datagram sockets, only the address of a peer specified in a previous connect call will be returned. Any address specified by a previous sendto call will not be returned by getpeername.

On call, the namelen parameter contains the size, in bytes, of the name buffer. On return, the namelen parameter contains the actual size, in bytes, of the name parameter returned.

Requirements
Client
Requires Windows Vista, Windows XP, Windows 2000 Professional, Windows NT Workstation, Windows Me, Windows 98, or Windows 95.

Server
Requires Windows Server 2008, Windows Server 2003, Windows 2000 Server, or Windows NT Server.

Header
Declared in Winsock2.h.

Library
Use Ws2_32.lib.

DLL
Requires Ws2_32.dll.

本小节介绍其他几个Winsock API函数,它们在实际网络应用中非常有用。
1. getpeername

166计计第二部分附Winsock API
下载
该函数用于获得通信方的套接字地址信息,该信息是关于已建立连接的那个套接字的。
它的定义如下:
第一个参数是准备连接的套接字,后两个参数则是指向基层协议类型及其长度的指针。
对数据报套接字来说,这个函数返回的是投向连接调用的那个地址;但不会返回投向 s e n d t o或
W S A S e n d To调用的那个地址。
2. getsockname
该函数是g e t s o c k n a m e的对应函数。它返回的是指定套接字的本地接口的地址信息。它的
定义如下:
除了套接字s返回的地址信息本地地址信息外,它的参数和g e t p e e r n a m e的参数都是一样的。
T C P协议中,这个地址和监听指定端口和I P接口的那个服务器套接字是一样的。
Fighting Horse 2008-10-06
  • 打赏
  • 举报
回复
用 getsockname
int getsockname(int socket, struct sockaddr *restrict address,
socklen_t *restrict address_len);
baihacker 2008-10-06
  • 打赏
  • 举报
回复
getsockname Function

The getsockname function retrieves the local name for a socket.


int getsockname(
__in SOCKET s,
__out struct sockaddr* name,
__in_out int* namelen
);

Parameters
s
Descriptor identifying a socket.

name
Pointer to a SOCKADDR structure that receives the address (name) of the socket.

namelen
Size of the name buffer, in bytes.

Return Value
If no error occurs, getsockname returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error code Meaning
WSANOTINITIALISED
A successful WSAStartup call must occur before using this API.

WSAENETDOWN
The network subsystem has failed.

WSAEFAULT
The name or the namelen parameter is not a valid part of the user address space, or the namelen parameter is too small.

WSAEINPROGRESS
A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.

WSAENOTSOCK
The descriptor is not a socket.

WSAEINVAL
The socket has not been bound to an address with bind, or ADDR_ANY is specified in bind but connection has not yet occurred.


Remarks
The getsockname function retrieves the current name for the specified socket descriptor in name. It is used on the bound or connected socket specified by the s parameter. The local association is returned. This call is especially useful when a connect call has been made without doing a bind first; the getsockname function provides the only way to determine the local association that has been set by the system.

On call, the namelen parameter contains the size of the name buffer, in bytes. On return, the namelen parameter contains the actual size in bytes of the name parameter.

The getsockname function does not always return information about the host address when the socket has been bound to an unspecified address, unless the socket has been connected with connect or accept (for example, using ADDR_ANY). A Windows Sockets application must not assume that the address will be specified unless the socket is connected. The address that will be used for the socket is unknown unless the socket is connected when used in a multihomed host. If the socket is using a connectionless protocol, the address may not be available until I/O occurs on the socket.

Requirements
Client
Requires Windows Vista, Windows XP, Windows 2000 Professional, Windows NT Workstation, Windows Me, Windows 98, or Windows 95.

Server
Requires Windows Server 2008, Windows Server 2003, Windows 2000 Server, or Windows NT Server.

Header
Declared in Winsock2.h.

Library
Use Ws2_32.lib.

DLL
Requires Ws2_32.dll.

runningdog_1 2008-10-06
  • 打赏
  • 举报
回复
楼主的意思是:创建一个普通的套接字,应用程序通过该套接字收到的数据根本没有IP头信息,连传输层的信息都没有,只有用户数据。
ysuliu 2008-10-06
  • 打赏
  • 举报
回复
好像是有~
[Quote=引用 2 楼 k2eats 的回复:]
楼主看看TCP/IP详解,
IP包首部就有源IP和目的IP地址
[/Quote]
K行天下 2008-10-06
  • 打赏
  • 举报
回复
楼主看看TCP/IP详解,
IP包首部就有源IP和目的IP地址
baihacker 2008-10-06
  • 打赏
  • 举报
回复
http://topic.csdn.net/t/20021212/11/1253946.html

在IP协议中有目标IP的...直接解析就OK了.

24,854

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧