Linux系统下socket通信注意之bind函数

        一般我们在测试C/S程序的时候,为了方便。一般客户端连接服务器的时候,我们会不注意客户端的ip与端口,我们只关注的是服务器端的ip与端口,这样我们就可以与server通信。

       在tcp/ip协议中,我们看到TCP或者UDP数据帧,都含有源地址、源端口与目的地址、目的端口。在socket编程中,创建一个socket句柄,都会有本地的一个IP与端口对应,这个就是源地址与源端口。如果我们在程序中不指定这个源地址与源端口会怎么样呢?这里指定的时候我们采用bind函数进行绑定地址与端口。

        如果一个TCP客户端或者服务器没有调用bind进行绑定,因为在调用socket函数创建套接字的时候,内核还没有为套接字分配地址及其端口,当调用connect或者listen函数的时候,内核就要为相应的套接字选择一个临时的端口与地址。

在讨论bind函数之前,需要对网络地址端口格式进行了解:

通用的网络地址标识为sockaddr,为了使不同格式的地址能够传入到套接字函数,地址需要被强制转换成sockaddr类型。其结构如下:

struct sockaddr{
     sa_family_t sa_family;
     char sa_data[];
     ......
}
套接字可以实现添加额外成员到sa_data中,Linux中此成员为sa_data[14]。
Internet的地址定义在<netinet/in.h>,在IPV4因特网中(AF_INET)中,套接字的地址结构如下:

struct sockaddr_in{
      sa_family_t sin_family;
      in_port_t sin_port;
      struct in_addr sin_addr;
}
struct in_addr{
      in_addr_t s_addr;
}
然后bind函数的原型如下:

int bind(int sockfd,const struct sockaddr *addr,socklen_t len);
成功调用返回0,出错返回-1;
下面展示一个客户端绑定本地地址与端口的实例:

/*server ip and port*/
          struct sockaddr_in servaddr;
          bzero(&servaddr,sizeof(servaddr));
          servaddr.sin_family = AF_INET;
          servaddr.sin_addr.s_addr = inet_addr(argv[1]);
          servaddr.sin_port = htons(atoi(argv[2]));
          /*local ip and port*/
          struct sockaddr_in cltaddr;
          bzero(&cltaddr,sizeof(cltaddr));
          cltaddr.sin_family = AF_INET;
          cltaddr.sin_addr.s_addr = inet_addr(argv[3]);
          cltaddr.sin_port = htons(atoi(argv[4]));
          /*create socket*/
         sockfd =socket(AF_INET,SOCK_STREAM,0);
         if(sockfd<0){
            printf("create socket error...\n");
            exit(1);
         }
          int reuse = 1;
          setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int));
         if((bind(sockfd,(struct sockaddr*)&cltaddr,sizeof(cltaddr)))<0){
                 printf("can not bind....\n");
                 exit(1);
          }
此例子中,cltaddr代表需要绑定的本地地址信息。



  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Linux操作系统下,可以使用SocketCAN来进行CAN总线通信SocketCAN是一个通用的CAN设备驱动和套接字接口,它提供了一种基于套接字的API来访问CAN设备。 首先,需要确保系统内核中加载了CAN设备驱动。可以通过modprobe命令来加载对应的内核模块。例如,对于CAN设备驱动“can0”,可以使用以下命令加载该模块: ``` sudo modprobe can sudo modprobe can_raw sudo modprobe vcan ``` 接下来,需要创建一个CAN设备接口,在这个接口上进行通信。可以使用以下命令创建一个CAN设备接口: ``` sudo ip link set can0 type can bitrate 250000 sudo ifconfig can0 up ``` 上述命令中的“can0”为设备接口名称,可以根据需要自行指定。而“bitrate 250000”设置了CAN总线的波特率为250kbps,也可以根据实际需求调整波特率。 在CAN设备接口创建成功后,就可以使用SocketCAN来进行CAN总线通信了。可以使用C语言或者其他编程语言进行开发。 在C语言中,可以使用socket函数创建一个套接字,并调用相应的API函数来发送和接收CAN消息。具体的代码实现可以参考SocketCAN的官方文档和示例代码。 总之,通过使用SocketCAN,可以很方便地在Linux系统下进行CAN总线通信,实现CAN消息的发送和接收。同时,可以根据实际需求进行定制开发,以满足特定的应用场景。 ### 回答2: 在Linux下,使用SocketCAN可以进行CAN总线通信SocketCAN是Linux内核中的一种CAN总线子系统,它提供了一组API函数,使开发者可以通过套接字接口访问CAN总线。 首先,在使用SocketCAN之前,需要确保Linux内核已经加载了can和can-raw的驱动模块。可以通过执行命令`sudo modprobe can`和`sudo modprobe can-raw`加载这两个模块。 接下来,可以使用`socket()`函数创建一个套接字,并使用`bind()`函数将该套接字与CAN总线上的某个接口进行绑定。例如,可以使用`AF_CAN`作为地址族参数,使用`struct sockaddr_can`结构体来指定CAN接口的名称和其他参数。然后,使用`recvfrom()`函数从套接字中接收CAN帧数据,使用`sendto()`函数将CAN帧数据发送到套接字。在`recvfrom()`和`sendto()`函数的参数中,需要使用`struct can_frame`结构体来描述CAN帧的数据。 除了基本的接收和发送功能外,SocketCAN还提供了一些其他的功能,比如设置过滤器来屏蔽或接收特定ID的CAN帧,以及设置CAN总线的位速率等。这些功能可以通过使用`setsockopt()`函数,并指定`SOL_CAN_RAW`或`SOL_CAN_FILTER`等选项来实现。 总之,使用SocketCAN可以方便地在Linux下实现CAN总线通信。通过使用SocketCAN提供的API函数和结构体,开发者可以在Linux系统中直接使用套接字接口进行CAN数据的接收和发送,同时也可以利用SocketCAN提供的其他功能来优化CAN总线通信的处理。 ### 回答3: SocketCAN是一个开源的Linux内核网络层协议栈,它提供了一种统一的接口,用于在Linux中进行CAN总线通信。它能够实现CAN硬件的底层访问和CAN消息的发送和接收,提供了一些有用的工具和库,方便开发人员进行CAN总线应用程序的开发。 在Linux中使用SocketCAN进行CAN总线通信,首先需要加载CAN网络驱动模块。然后,可以使用工具如candump和cansend来发送和接收CAN消息。candump用于监听CAN总线上的消息,而cansend用于发送CAN消息。 另外,SocketCAN还提供了一组C语言库函数,可以用于在程序中进行CAN总线通信。这些库函数可以方便地创建和绑定CAN套接字,发送和接收CAN消息。通过设置套接字的选项,还可以实现CAN过滤和接收超时等功能。 使用SocketCAN进行CAN总线通信的好处是,它可以提供高性能和低延迟的数据传输。此外,SocketCAN还支持多个CAN网络接口的管理,可以同时与多个CAN总线通信。 总而言之,使用SocketCAN进行CAN总线通信可以方便地在Linux中开发和调试CAN总线应用程序,提供了一套完整的硬件访问、消息发送和接收的工具和库函数

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值