#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define GVCP_PORT 3956
#define GVCP_VERSION 0x0001
#define GVCP_FLAG_REQUEST_ACK 0x0001
#define GVCP_FLAG_REQUEST_RESEND 0x0002

struct gvcp_header {
    uint16_t flags;
    uint16_t command;
    uint16_t length;
    uint16_t request_id;
};

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <camera IP address>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    const char *ip_addr = argv[1];

    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(ip_addr);
    server_addr.sin_port = htons(GVCP_PORT);

    struct gvcp_header header;
    memset(&header, 0, sizeof(header));
    header.flags = htons(GVCP_FLAG_REQUEST_ACK);
    header.command = htons(0x0001); // read register command
    header.length = htons(0x0004); // read 4 bytes
    header.request_id = htons(0x0001);

    ssize_t bytes_sent = sendto(sockfd, &header, sizeof(header), 0,
                                (struct sockaddr *) &server_addr, sizeof(server_addr));
    if (bytes_sent < 0) {
        perror("sendto");
        exit(EXIT_FAILURE);
    }

    struct gvcp_header response_header;
    memset(&response_header, 0, sizeof(response_header));

    socklen_t addrlen = sizeof(server_addr);
    ssize_t bytes_received = recvfrom(sockfd, &response_header, sizeof(response_header), 0,
                                      (struct sockaddr *) &server_addr, &addrlen);
    if (bytes_received < 0) {
        perror("recvfrom");
        exit(EXIT_FAILURE);
    }

    printf("Response header: flags=0x%04x command=0x%04x length=0x%04x request_id=0x%04x\n",
           ntohs(response_header.flags), ntohs(response_header.command),
           ntohs(response_header.length), ntohs(response_header.request_id));

    close(sockfd);

    return 0;
}

这个程序使用了标准C库和网络编程相关的库函数。它创建了一个UDP socket并发送了一个GVCP消息,读取了4个字节的寄存器值,并接收响应消息。最后,它输出响应消息的头部信息。注意,在实际应用中,你需要根据自己的相机和应用程序的需求来修改代码。