日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

socket通过多网卡收发数据

發布時間:2025/3/21 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 socket通过多网卡收发数据 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.?? 通過bind機制,?? socket必須要調用bind才能發送tcp包。 bind調用時需要一個ip地址。一般一臺機器的多網口都要配置不同的ip地址(路由器除外,路由器是一個網橋設備,只是負責轉發包,所以其它的端口一般沒有ip地址)。

2.?? 通過ioctl來設置打開的socket.???? (ioctl (fd, SIOCGIFINDEX, &ifr)==0;

?

TCP編程時不管是客戶端還是服務器端,都要調用bind后才能連接/收發數據。

UDP在客戶端時可以不調用bind而直接使用recvfrom/sendto來收發數據。?

在客戶端一般是本地地址選擇INETADDR_ANY, 表示所有網絡接口。

?

代碼如下:

#include <stdio.h>;
#include <string.h>;
#include <sys/socket.h>;
#include <netpacket/packet.h>;
#include <net/ethernet.h>;
#include <sys/ioctl.h>;
#include <net/if.h>;
#include <assert.h>;


int
main ()
{
? ?? ???struct sockaddr_ll sll;
? ?? ???int fd;
? ?? ???struct ifreq ifr;
? ?? ???char *dev;

? ?? ???fd = socket (PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

? ?? ???dev = "eth0";
? ?? ???strncpy ((char *)ifr.ifr_name, dev, sizeof(ifr.ifr_name));
? ?? ???assert (ioctl (fd, SIOCGIFINDEX, &ifr)==0);

? ?? ???memset (&sll, 0, sizeof(sll));
? ?? ???sll.sll_family = AF_PACKET;
? ?? ???sll.sll_protocol = htons (ETH_P_ALL);
? ?? ???sll.sll_ifindex = ifr.ifr_ifindex;

? ?? ???assert (bind (fd, (struct sockaddr *)&sll, sizeof(sll))==0);

}

?

?

?

?

##############################################################

?

?

?

Windows網絡編程總結(一)
作者: ? Kendiv
出處: ? CSDN.NET ?

  關于bind:

  INADDR_ANY ? 的具體含義是,綁定到0.0.0.0。此時,對所有的地址都將是有效的,如果系統考慮冗余,采用多個網卡的話,那么使用此種bind,將在所有網卡上進行綁定。在這種情況下,你可以收到發送到所有有效地址上數據包。

  例如:

  SOCKADDR_IN ? Local;

  Local.sin_addr.s_addr ? = ? htonl(INADDR_ANY);

  
  另外一種方式如下:

  SOCKADDR_IN ? Local;

  hostent* ? thisHost ? = ? gethostbyname( " ");

  char* ? ip ? = ? inet_ntoa(*(struct ? in_addr ? *)*thisHost-> h_addr_list);

  Local.sin_addr.s_addr ? = ? inet_addr(ip);

  在這種方式下,將在系統中當前第一個可用地址上進行綁定。在多網卡的環境下,可能會出問題。

  
  最常見的方式:

  const ? char ? LocalIP[] ? = ? "192.168.0.100 ";

  SOCKADDR_IN ? Local;

  Local.sin_addr.s_addr ? = ? inet_addr(LocalIP);

  bind(socket, ? (LPSOCKADDR)&Local, ? sizeof(SOCKADDR_IN)


  bind的安全問題:

  如果你在bind時,使用了INADDR_ANY那么,你將可以在所有有效的地址上進行監聽,但是Socket有一個特性:可在同一端口上綁定多個Socket。

  讓我們看看下面的情況:假設你的系統只有一個IP:192.168.0.100,你希望bind到4096端口。對于下面的兩種bind,當數據包到達時,誰會接收到呢?

  Local.sin_addr.s_addr ? = ? htonl(INADDR_ANY);

  Local.sin_addr.s_addr ? = ? inet_addr(“192.168.0.100”);


  WinSocke庫是這樣處理的:誰綁定的最明確,誰獲取數據包。顯然,第二種bind將獲取到達的數據包。如果避免這種情況呢?使用SO_EXECLUSINEADDRUSE選項。需要注意的是,此選項在Windows ? NT ? 4 ? Service ? Pack ? 4以后(包括SP4)才可以使用。

  示例代碼:

  #ifndef ? SO_EXECLUSINEADDRUSE

  #define ? SO_EXECLUSINEADDRUSE ? ((int)(~SO_REUSEADDR))

  #endif
  

  SOCKADDR_IN ? Local;

  BOOL ? val ? = ? TRUE;

  
  Local. ? sin_family ? = ? AF_INET;

  Local. ? sin_port ? = ? htons(4096);

  Local.sin_addr.s_addr ? = ? htonl(INADDR_ANY);

  
  setsocketopt(socket,

  SOL_SOCKET,

  SO_EXECLUSINEADDRUSE,

  (char*)&val,

  sizeof(val));

  
  bind(socket, ? (LPSOCKADDR)&Local, ? sizeof(SOCKADDR_IN)

總結

以上是生活随笔為你收集整理的socket通过多网卡收发数据的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。