利用Linux socket 模拟大华IPC发送广播包,让大华客户端搜索到一个模拟的ip摄像头

 最近在熟悉IP摄像头的网络通讯,做了个简单的实例,现在整理一下思路。

 大概就是拿到一个大华IP摄像头,wireshark抓包分析它是如何回应大华客户端发出的广播包,然后通过Linux创建UDP,模拟ip摄像头设备发出同样的广播包。然后在大华的视频客户端点击自动搜索的时候能搜索到一个虚拟的IP摄像头设备。但是这个设备是不存在的,只是个虚拟的。

 首先我们需要通过抓包工具,查看当我们点击自动搜索时,我们的摄像头设备是如何回应客户端发送的广播包的。图中 192.168.1.36是我的设备。

 图中蓝色部分的UDP协议就是当点击自动搜素时发送的广播包,我的设备回应的包就是长度为839的包,其中真正的数据长度为797。

查看原始数据如图。


分析数据包的工作做完后,就可以开始模拟了。我所使用的方法时在linux下创建UDP发送相同的包,让大华客户端识别。下面是UDP的代码

#include<stdlib.h> 
#include<stdio.h> 
#include<string.h> 
#include<sys/types.h> 
#include<netinet/in.h> 
#include<netdb.h> 
#include<sys/socket.h> 
#include<sys/wait.h> 
#include<arpa/inet.h> 

#define BUFFER_SIZE 794

int main(){ 
 int sockListen;  
 int recvbytes; 
 char recvbuf[128]; 
 char buffer[BUFFER_SIZE] = {0x20, 0x00, 0x00, 0x00, 0x44, 0x48, 0x49, 0x50,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0xfd, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0xfd, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x7b, 0x20, 0x22, 0x6d, 0x61, 0x63, 0x22, 0x20,
 0x3a, 0x20, 0x22, 0x34, 0x63, 0x3a, 0x31, 0x31,
 0x3a, 0x62, 0x66, 0x3a, 0x39, 0x65, 0x3a, 0x39,
 0x32, 0x3a, 0x30, 0x63, 0x22, 0x2c, 0x20, 0x22,
 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x22, 0x20,
 0x3a, 0x20, 0x22, 0x63, 0x6c, 0x69, 0x65, 0x6e,
 0x74, 0x2e, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79,
 0x44, 0x65, 0x76, 0x49, 0x6e, 0x66, 0x6f, 0x22,
 0x2c, 0x20, 0x22, 0x70, 0x61, 0x72, 0x61, 0x6d,
 0x73, 0x22, 0x20, 0x3a, 0x20, 0x7b, 0x20, 0x22,
 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e,
 0x66, 0x6f, 0x22, 0x20, 0x3a, 0x20, 0x7b, 0x20,
 0x22, 0x41, 0x6c, 0x61, 0x72, 0x6d, 0x49, 0x6e,
 0x70, 0x75, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e,
 0x65, 0x6c, 0x73, 0x22, 0x20, 0x3a, 0x20, 0x30,
 0x2c, 0x20, 0x22, 0x41, 0x6c, 0x61, 0x72, 0x6d,
 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x43, 0x68,
 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x22, 0x20,
 0x3a, 0x20, 0x30, 0x2c, 0x20, 0x22, 0x44, 0x65,
 0x76, 0x69, 0x63, 0x65, 0x43, 0x6c, 0x61, 0x73,
 0x73, 0x22, 0x20, 0x3a, 0x20, 0x22, 0x49, 0x50,
 0x43, 0x22, 0x2c, 0x20, 0x22, 0x44, 0x65, 0x76,
 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22,
 0x20, 0x3a, 0x20, 0x22, 0x49, 0x50, 0x43, 0x2d,
 0x48, 0x44, 0x57, 0x34, 0x34, 0x32, 0x36, 0x43,
 0x22, 0x2c, 0x20, 0x22, 0x48, 0x74, 0x74, 0x70,
 0x50, 0x6f, 0x72, 0x74, 0x22, 0x20, 0x3a, 0x20,
 0x38, 0x30, 0x2c, 0x20, 0x22, 0x49, 0x50, 0x76,
 0x34, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
 0x22, 0x20, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x44,
 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x47, 0x61,
 0x74, 0x65, 0x77, 0x61, 0x79, 0x22, 0x20, 0x3a,
 0x20, 0x22, 0x31, 0x39, 0x32, 0x2e, 0x31, 0x36,
 0x38, 0x2e, 0x31, 0x2e, 0x31, 0x22, 0x2c, 0x20,
 0x22, 0x44, 0x68, 0x63, 0x70, 0x45, 0x6e, 0x61,
 0x62, 0x6c, 0x65, 0x22, 0x20, 0x3a, 0x20, 0x66,
 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x20, 0x22, 0x49,
 0x50, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
 0x22, 0x20, 0x3a, 0x20, 0x22, 0x31, 0x39, 0x32,
 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x31, 0x2e, 0x33,
 0x36, 0x22, 0x2c, 0x20, 0x22, 0x53, 0x75, 0x62,
 0x6e, 0x65, 0x74, 0x4d, 0x61, 0x73, 0x6b, 0x22,
 0x20, 0x3a, 0x20, 0x22, 0x32, 0x35, 0x35, 0x2e,
 0x32, 0x35, 0x35, 0x2e, 0x32, 0x35, 0x35, 0x2e,
 0x30, 0x22, 0x20, 0x7d, 0x2c, 0x20, 0x22, 0x49,
 0x50, 0x76, 0x36, 0x41, 0x64, 0x64, 0x72, 0x65,
 0x73, 0x73, 0x22, 0x20, 0x3a, 0x20, 0x7b, 0x20,
 0x22, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74,
 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x22,
 0x20, 0x3a, 0x20, 0x22, 0x32, 0x30, 0x30, 0x38,
 0x3a, 0x3a, 0x31, 0x22, 0x2c, 0x20, 0x22, 0x44,
 0x68, 0x63, 0x70, 0x45, 0x6e, 0x61, 0x62, 0x6c,
 0x65, 0x22, 0x20, 0x3a, 0x20, 0x66, 0x61, 0x6c,
 0x73, 0x65, 0x2c, 0x20, 0x22, 0x49, 0x50, 0x41,
 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x20,
 0x3a, 0x20, 0x22, 0x32, 0x30, 0x30, 0x38, 0x3a,
 0x3a, 0x36, 0x5c, 0x2f, 0x31, 0x31, 0x32, 0x22,
 0x2c, 0x20, 0x22, 0x4c, 0x69, 0x6e, 0x6b, 0x4c,
 0x6f, 0x63, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72,
 0x65, 0x73, 0x73, 0x22, 0x20, 0x3a, 0x20, 0x22,
 0x66, 0x65, 0x38, 0x30, 0x3a, 0x3a, 0x34, 0x65,
 0x31, 0x31, 0x3a, 0x62, 0x66, 0x66, 0x66, 0x3a,
 0x66, 0x65, 0x39, 0x65, 0x3a, 0x39, 0x32, 0x30,
 0x63, 0x5c, 0x2f, 0x36, 0x34, 0x22, 0x20, 0x7d,
 0x2c, 0x20, 0x22, 0x4d, 0x61, 0x63, 0x68, 0x69,
 0x6e, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x20,
 0x3a, 0x20, 0x22, 0x31, 0x43, 0x30, 0x33, 0x43,
 0x31, 0x41, 0x50, 0x41, 0x41, 0x30, 0x30, 0x30,
 0x38, 0x39, 0x22, 0x2c, 0x20, 0x22, 0x4d, 0x61,
 0x6e, 0x75, 0x66, 0x61, 0x63, 0x74, 0x75, 0x72,
 0x65, 0x72, 0x22, 0x20, 0x3a, 0x20, 0x22, 0x44,
 0x61, 0x68, 0x75, 0x61, 0x22, 0x2c, 0x20, 0x22,
 0x50, 0x6f, 0x72, 0x74, 0x22, 0x20, 0x3a, 0x20,
 0x33, 0x37, 0x37, 0x37, 0x37, 0x2c, 0x20, 0x22,
 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x56, 0x69,
 0x64, 0x65, 0x6f, 0x49, 0x6e, 0x70, 0x75, 0x74,
 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73,
 0x22, 0x20, 0x3a, 0x20, 0x30, 0x2c, 0x20, 0x22,
 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, 0x6f,
 0x22, 0x20, 0x3a, 0x20, 0x22, 0x31, 0x43, 0x30,
 0x33, 0x43, 0x31, 0x41, 0x50, 0x41, 0x41, 0x30,
 0x30, 0x30, 0x38, 0x39, 0x22, 0x2c, 0x20, 0x22,
 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x22, 0x20,
 0x3a, 0x20, 0x22, 0x44, 0x61, 0x68, 0x75, 0x61,
 0x22, 0x2c, 0x20, 0x22, 0x56, 0x65, 0x72, 0x73,
 0x69, 0x6f, 0x6e, 0x22, 0x20, 0x3a, 0x20, 0x22,
 0x32, 0x2e, 0x34, 0x30, 0x30, 0x2e, 0x30, 0x30,
 0x30, 0x30, 0x2e, 0x33, 0x34, 0x2e, 0x52, 0x22,
 0x2c, 0x20, 0x22, 0x56, 0x69, 0x64, 0x65, 0x6f,
 0x49, 0x6e, 0x70, 0x75, 0x74, 0x43, 0x68, 0x61,
 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x22, 0x20, 0x3a,
 0x20, 0x31, 0x2c, 0x20, 0x22, 0x56, 0x69, 0x64,
 0x65, 0x6f, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74,
 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73,
 0x22, 0x20, 0x3a, 0x20, 0x31, 0x36, 0x20, 0x7d,
 0x20, 0x7d, 0x20, 0x7d, 0x00};
 
 int addrLen = sizeof(struct sockaddr_in); 

 if((sockListen = socket(AF_INET, SOCK_DGRAM, 0)) == -1){ 
  printf("socket fail\n"); 
  return -1; 
 } 

 int set = 1; 
 setsockopt(sockListen, SOL_SOCKET, SO_BROADCAST | SO_REUSEADDR, &set, sizeof(int)); 

 struct sockaddr_in recvAddr;  
 recvAddr.sin_family = AF_INET; 
 recvAddr.sin_port = htons(5050); 
 recvAddr.sin_addr.s_addr = INADDR_ANY; 
 memset(recvAddr.sin_zero, 0, 8);

 // 必须绑定,否则无法监听 
 if(bind(sockListen, (struct sockaddr *)&recvAddr, sizeof(struct sockaddr)) == -1){ 
  printf("bind fail\n"); 
  return -1; 
 } 


 struct sockaddr_in send_addr;

 send_addr.sin_family = AF_INET;
 send_addr.sin_addr.s_addr = inet_addr("255.255.255.255");
 send_addr.sin_port = htons(37810);
 memset(send_addr.sin_zero, 0, 8);
 
 socklen_t server_addr_length = sizeof(send_addr);


 /* 数据收发 */
 if((recvbytes = recvfrom(sockListen, recvbuf, 128, 0, 
 (struct sockaddr *)&recvAddr, &addrLen)) != -1)
 { 
  
  recvbuf[recvbytes] = '\0'; 
  printf("receive a broadCast messgse:%s\n", recvbuf); 
  
  /* 收到广播包后回一个广播包 */

  sendto(sockListen,buffer,BUFFER_SIZE,0,(struct sockaddr*)&send_addr,sizeof(struct sockaddr));
  printf("send packet success!\n");
  
 }
 else
 { 
  printf("recvfrom fail\n"); 
 } 

 
 close(sockListen); 

 return 0; 

在linux下编译执行就可以了。

本人小白一枚,刚到公司实习。对于广播包,心跳包的概念刚刚建立,希望通过小小的实验能有所收获。现在对该实验作个小小的记录。也是第一次写文章,希望从事安防的大牛们的多多支持。也希望通过这样的方式能加强自己写文章的水平。



  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的Socket聊天程序的示例代码,其中一个服务端和两个客户端: 服务端代码: ```python import socket import threading def handle_client(client_socket, addr): while True: data = client_socket.recv(1024) if not data: break print("[{}] {}".format(addr, data.decode())) client_socket.sendall("[Echo]: {}".format(data.decode()).encode()) print("[{}] disconnected".format(addr)) client_socket.close() def start_server(): server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_socket.bind(("localhost", 8888)) server_socket.listen(5) print("[Server] Listening on port 8888...") while True: client_socket, addr = server_socket.accept() print("[Server] New client connected: {}".format(addr)) client_thread = threading.Thread(target=handle_client, args=(client_socket, addr)) client_thread.start() if __name__ == '__main__': start_server() ``` 客户端1代码: ```python import socket def start_client(): client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect(("localhost", 8888)) while True: message = input("[You]: ") if message == "exit": break client_socket.sendall(message.encode()) data = client_socket.recv(1024) print("[Server]: {}".format(data.decode())) print("[Client] Disconnected") client_socket.close() if __name__ == '__main__': start_client() ``` 客户端2代码: ```python import socket def start_client(): client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect(("localhost", 8888)) while True: message = input("[You]: ") if message == "exit": break client_socket.sendall(message.encode()) data = client_socket.recv(1024) print("[Server]: {}".format(data.decode())) print("[Client] Disconnected") client_socket.close() if __name__ == '__main__': start_client() ``` 运行以上代码,打开两个客户端并连接到服务端,即可模拟Socket聊天程序的基本功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值