精华内容
下载资源
问答
  • C中数据包的读/写处理示例
    2021-05-21 17:58:05

    如果我理解正确,你会问,“服务器如何理解客户端发送的信息”?

    如果这就是您所要求的,答案很简单:提前双方同意每个使用的数据结构都是兼容的.即你决定提前通信协议.

    因此,例如,如果我有一个客户端 – 服务器应用程序,客户端连接并可以询问诸如“时间”,“日期”之类的事情,并且可以说“settime”和“setdate”,我需要编写我的服务器一种它将理解这些命令的方式.

    显然,在上述情况下,它是微不足道的,因为它只是一个基于文本的协议.但是,假设您正在编写一个将返回信息结构的应用程序,即

    struct Person {

    char* name;

    int age;

    int heightInInches;

    // ... other fields ...

    };

    您可以从服务器/客户端编写整个结构.在这种情况下,有几点需要注意:

    >你需要正确地使用hton / ntoh

    >您需要确保您的客户端和服务器都能理解相关的结构.

    >您可能也可能不必在4B边界上对齐(因为如果不这样做,不同的C编译器可能会执行不同的操作,这可能会在客户端和服务器之间烧毁,或者可能不会).

    但是,一般而言,在编写客户端/服务器应用程序时,最重要的是通信协议.

    不过,我不确定这是否能完全回答你的问题.这就是你所追求的,或者你是否在询问更多关于如何使用send / recv函数?

    更多相关内容
  • 使用C语言实现原始套接字从数据链路层到应用层的操作,Linux系统
  • 实际上,它包含上百个功能的协议,如ICMP(互联网控制信息协议)、FTP(文件传输协议)、UDP(用户数据包协议)、ARP(地址解析协议)等。TCP负责发现传输的问题,一旦有问题就会发出重传信号,直到所有数据安全正确...
  • 我正在尝试用C创建一个ICMP ping测试程序,但是在成功发送数据包时遇到了困难. sendto函数返回字节数和所有内容但实际上没有发送数据包.我已经在目标计算机上使用WireShark验证了这一点.主机上的常规ping工作正常,但...

    我正在尝试用C创建一个ICMP ping测试程序,但是在成功发送数据包时遇到了困难. sendto函数返回字节数和所有内容但实际上没有发送数据包.我已经在目标计算机上使用WireShark验证了这一点.主机上的常规ping工作正常,但在WireShark中显示.

    这是我的代码:

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    unsigned short cksum(unsigned short *addr, int len);

    int main(int argc, char *argv[])

    {

    int sock;

    char send_buf[400], recv_buf[400], src_name[256], src_ip[15], dst_ip[15];

    struct ip *ip = (struct ip *)send_buf;

    struct icmp *icmp = (struct icmp *)(ip + 1);

    struct hostent *src_hp, *dst_hp;

    struct sockaddr_in src, dst;

    struct timeval t;

    int on;

    int num = 10;

    int failed_count = 0;

    int bytes_sent, bytes_recv;

    int dst_addr_len;

    int result;

    fd_set socks;

    /* Initialize variables */

    on = 1;

    memset(send_buf, 0, sizeof(send_buf));

    /* Check for valid args */

    if(argc < 2)

    {

    printf("\nUsage: %s \n", argv[0]);

    printf("- dst_server is the target\n");

    exit(EXIT_FAILURE);

    }

    /* Check for root access */

    if (getuid() != 0)

    {

    fprintf(stderr, "%s: This program requires root privileges!\n", argv[0]);

    exit(EXIT_FAILURE);

    }

    /* Get source IP address */

    if(gethostname(src_name, sizeof(src_name)) < 0)

    {

    perror("gethostname() error");

    exit(EXIT_FAILURE);

    }

    else

    {

    if((src_hp = gethostbyname(src_name)) == NULL)

    {

    fprintf(stderr, "%s: Can't resolve, unknown source.\n", src_name);

    exit(EXIT_FAILURE);

    }

    else

    ip->ip_src = (*(struct in_addr *)src_hp->h_addr);

    }

    /* Get destination IP address */

    if((dst_hp = gethostbyname(argv[1])) == NULL)

    {

    if((ip->ip_dst.s_addr = inet_addr(argv[1])) == -1)

    {

    fprintf(stderr, "%s: Can't resolve, unknown destination.\n", argv[1]);

    exit(EXIT_FAILURE);

    }

    }

    else

    {

    ip->ip_dst = (*(struct in_addr *)dst_hp->h_addr);

    dst.sin_addr = (*(struct in_addr *)dst_hp->h_addr);

    }

    sprintf(src_ip, "%s", inet_ntoa(ip->ip_src));

    sprintf(dst_ip, "%s", inet_ntoa(ip->ip_dst));

    printf("Source IP: '%s' -- Destination IP: '%s'\n", src_ip, dst_ip);

    /* Create RAW socket */

    if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)

    {

    perror("socket() error");

    /* If something wrong, just exit */

    exit(EXIT_FAILURE);

    }

    /* Socket options, tell the kernel we provide the IP structure */

    if(setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0)

    {

    perror("setsockopt() for IP_HDRINCL error");

    exit(EXIT_FAILURE);

    }

    /* IP structure, check the ip.h */

    ip->ip_v = 4;

    ip->ip_hl = 5;

    ip->ip_tos = 0;

    ip->ip_len = htons(sizeof(send_buf));

    ip->ip_id = htons(321);

    ip->ip_off = htons(0);

    ip->ip_ttl = 255;

    ip->ip_p = IPPROTO_ICMP;

    ip->ip_sum = 0;

    /* ICMP structure, check ip_icmp.h */

    icmp->icmp_type = ICMP_ECHO;

    icmp->icmp_code = 0;

    icmp->icmp_id = 123;

    icmp->icmp_seq = 0;

    /* Set up destination address family */

    dst.sin_family = AF_INET;

    /* Loop based on the packet number */

    for(int i = 1; i <= num; i++)

    {

    /* Header checksums */

    icmp->icmp_cksum = 0;

    ip->ip_sum = cksum((unsigned short *)send_buf, ip->ip_hl);

    icmp->icmp_cksum = cksum((unsigned short *)icmp, sizeof(send_buf) - sizeof(struct icmp));

    /* Get destination address length */

    dst_addr_len = sizeof(dst);

    /* Set listening timeout */

    t.tv_sec = 5;

    t.tv_usec = 0;

    /* Set socket listening descriptors */

    FD_ZERO(&socks);

    FD_SET(sock, &socks);

    /* Send packet */

    if((bytes_sent = sendto(sock, send_buf, sizeof(send_buf), 0, (struct sockaddr *)&dst, dst_addr_len)) < 0)

    {

    perror("sendto() error");

    failed_count++;

    printf("Failed to send packet.\n");

    fflush(stdout);

    }

    else

    {

    printf("Sent %d byte packet... ", bytes_sent);

    fflush(stdout);

    /* Listen for the response or timeout */

    if((result = select(sock + 1, &socks, NULL, NULL, &t)) < 0)

    {

    perror("select() error");

    failed_count++;

    printf("Error receiving packet!\n");

    }

    else if (result > 0)

    {

    printf("Waiting for packet... ");

    fflush(stdout);

    if((bytes_recv = recvfrom(sock, recv_buf, sizeof(ip) + sizeof(icmp) + sizeof(recv_buf), 0, (struct sockaddr *)&dst, (socklen_t *)&dst_addr_len)) < 0)

    {

    perror("recvfrom() error");

    failed_count++;

    fflush(stdout);

    }

    else

    printf("Received %d byte packet!\n", bytes_recv);

    }

    else

    {

    printf("Failed to receive packet!\n");

    failed_count++;

    }

    fflush(stdout);

    icmp->icmp_seq++;

    }

    }

    /* Display success rate */

    printf("Ping test completed with %d%% success rate.\n", (((num - failed_count) / num) * 100));

    /* close socket */

    close(sock);

    return 0;

    }

    /* One's Complement checksum algorithm */

    unsigned short cksum(unsigned short *addr, int len)

    {

    int nleft = len;

    int sum = 0;

    unsigned short *w = addr;

    unsigned short answer = 0;

    while (nleft > 1)

    {

    sum += *w++;

    nleft -= 2;

    }

    if (nleft == 1)

    {

    *(unsigned char *)(&answer) = *(unsigned char *)w;

    sum += answer;

    }

    sum = (sum >> 16) + (sum & 0xffff);

    sum += (sum >> 16);

    answer = ~sum;

    return (answer);

    }

    对我做错了什么的想法?校验和还好吗?两者都使用0可以吗?

    编辑:好的,所以我设法得到正确发送的数据包,感谢下面的人!目标计算机将发回回信回复.但是,现在,我的程序没有收到答复. select()函数总是超时.我已经更新了上面的代码.

    编辑2:好吧,我已经开始工作了!我需要将套接字协议设置为IPPROTO_ICMP而不是IPPROTO_RAW,它工作得很好!再次感谢你们的评论!真有帮助!看起来我只能将一个答案标记为正确,但你们都帮助解决这个问题. 🙂

    展开全文
  • 指针pkt未在您的应用程序中定义.您有两种选择:1)将pkt声明为正常变量struct packet pkt;pkt.srcID = 01;....send(sockfd, &pkt, sizeof(struct packet), 0);2)当您的数据包包含一个后跟有效负载的标头时,第二种...

    指针pkt未在您的应用程序中定义.您有两种选择:

    1)将pkt声明为正常变量

    struct packet pkt;

    pkt.srcID = 01;

    ....

    send(sockfd, &pkt, sizeof(struct packet), 0);

    2)当您的数据包包含一个后跟有效负载的标头时,第二种方法很有用:

    char buffer[MAX_PACKET_SIZE];

    struct packet *pkt = (struct packet *) buffer;

    char *payload = buffer + sizeof(struct packet);

    int packet_size; /* should be computed as header size + payload size */

    pkt->srcID = 01;

    ...

    packet_size = sizeof(struct packet) /* + payload size */ ;

    send(sockfd, pkt, packet_size, 0);

    ....

    更新(回答你的评论):

    首先,您应该知道从TCP套接字接收可能不会提供整个数据包.您需要实现循环(如Nemo所建议)来读取整个数据包.由于您更喜欢第二个选项,因此您需要两个循环.第一个循环是读取数据包标头以提取有效负载大小,第二个循环是读取数据.在UDP的情况下,您不必担心部分接收.下面是一个示例代码(没有循环),其中sockfd是一个UDP套接字:

    char buffer[MAX_PACKET_SIZE];

    struct packet *pkt = (struct packet *) buffer;

    char *payload = buffer + sizeof(struct packet);

    int packet_size; /* should be computed as header size + payload size */

    .....

    /* read the whole packet */

    if (recv(sockfd, pkt, MAX_PACKET_SIZE, 0) < 0) {

    /* error in receiving the packet. It is up to you how to handle it */

    }

    /* Now, you can extract srcID as pkt->srcID */

    /* you can get data by processing payload variable */

    记得:*您需要实现其他用户提到的序列化* UDP是不可靠的传输协议,而TCP是可靠的传输协议.

    展开全文
  • 基于Linux使用C语言实现的一个串口通讯Demo,实测可用。
  • 分享一段基于UDP的单线程网络点对点数据包收发测试程序。这段程序我是用来测试使用recvmmsg()与sendmmsg()后的丢包率(这两个函数的信息可以man出来),使用g++编译,程序中可能有不足的地方还望指出。  文件一...

    分享一段基于UDP的单线程网络点对点数据包收发测试程序。这段程序我是用来测试使用recvmmsg()与sendmmsg()后的丢包率(这两个函数的信息可以man出来),使用g++编译,程序中可能有不足的地方还望指出。

      文件一:wrap.h

    #ifndef _WRAP_H_
    #define _WRAP_H
    
    #ifndef __USE_GNU
    #define __USE_GNU
    #endif
    
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <string.h>
    #include <stdio.h>
    #include <errno.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    
    #define DATNUM 100
    
    #endif


    文件二:server.c
    /* server.c */
    #include "wrap.h"
    #define SERV_PORT 8000
    
    int main(void)
    {
     struct sockaddr_in servaddr, clitaddr[DATNUM];
     int sockfd, i, n;
     char buf[DATNUM][3];
     struct mmsghdr msgvec[DATNUM];
     struct iovec dataiov[DATNUM];
     struct timespec *timeout;
     timeout = (struct timespec *)malloc(sizeof(struct timespec)); 
     unsigned long b = 0, a = 0;
     
     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    
     bzero(&servaddr, sizeof(servaddr));
     bzero(clitaddr, sizeof(clitaddr)); 
     bzero(msgvec, sizeof(msgvec));
     bzero(dataiov, sizeof(dataiov));
    
     servaddr.sin_family = AF_INET;
     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
     servaddr.sin_port = htons(SERV_PORT);
     bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
     timeout->tv_sec = 5;
     timeout->tv_nsec = 0;
     printf("Accepting connections ...\n");
    
     while(1) {
         for (i = 0; i < DATNUM; i++) {                 // 准备好待接收的包
                dataiov[i].iov_base = buf[i];
                dataiov[i].iov_len = 3;
                msgvec[i].msg_hdr.msg_name = &clitaddr;
                msgvec[i].msg_hdr.msg_namelen = 16;
                msgvec[i].msg_hdr.msg_iov = &dataiov[i];        
                msgvec[i].msg_hdr.msg_iovlen = DATNUM;
         }
         n = recvmmsg(sockfd, msgvec, DATNUM, 0, timeout);
         if (n == -1) {
             b++;
             printf("recv_err_num:%ld\n", b);          // 出错包数量
         }
        else {    
             a++;
             printf("recv_crt_num:%ld\n", a);          // 正确接收
         }
     }
    }

    文件三:client.c

    /* client.c */ 
    #include "wrap.h"
    #define SERV_PORT 8000
    
    int main(int argc, char *argv[])      // 参数是要发送的数据包个数
    {
    
     struct sockaddr_in servaddr;
     int sockfd, n, i, j, a;
     char m[6] = "CHINA";
     struct mmsghdr msgvec[DATNUM];
     struct iovec dataiov[DATNUM];
     
     if (argc != 2) {
        printf("Please input a argument.\n");
        exit(0);
     }
     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
     if (sockfd < 0) {
            printf("socket creating fail!\n");
            return 0;
     }
     bzero(&servaddr, sizeof(struct sockaddr_in));
     bzero(msgvec, sizeof(msgvec));
     bzero(dataiov, sizeof(dataiov));
     servaddr.sin_family = AF_INET;
     inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
     servaddr.sin_port = htons(SERV_PORT);
    
     for (i = 0, a = 0; i < atoi(argv[1]); i++) {
            for(j = 0; j < DATNUM; j++) {                // 构建数据包
                 bzero(&msgvec[j], sizeof(struct mmsghdr));
                 bzero(&dataiov[j], sizeof(struct iovec));
                 msgvec[j].msg_hdr.msg_name = &servaddr;
                 msgvec[j].msg_hdr.msg_namelen = 16;
                 dataiov[j].iov_base = &m;
                 dataiov[j].iov_len = 3;
                 msgvec[j].msg_hdr.msg_iov = &dataiov[j];
                 msgvec[j].msg_hdr.msg_iovlen = DATNUM;
            }
         
            n = sendmmsg(sockfd, msgvec, DATNUM, 0);
             if (n == -1) {
                 printf("sendmmsg error\n");
                exit(0);
            }
            else  a++;
    
            // usleep(1);     // 测试时最好注释掉,会影响结果
     }
     printf("send_num = %d\n", a);       
     return 0;
    }


    展开全文
  • Fragments.pcap是一个用wireshark工具捕捉数据包后的文件,用VC++或Linux的gcc工具实现下面三个任务,该怎么写C语言代码? 1.将IP Fragments.pcap中的分片数据包程序读取并打印每个分片的offset字段 2.将IP ...
  • /* 数据包长度,包括Header */ }NSS_HEADER; int str_echo(int sockfd, unsigned short no) { ssize_t readLen; ssize_t writeLen; char buf[8]; NSS_HEADER *hdr = (NSS_HEADER*)buf; memset( hdr, 0, sizeof(NSS_...
  • STC15W408AS_串口程序

    2021-02-26 15:59:45
    测试单片机型号:STC15W408AS 注意事项 1.串口波特率使用的是定时器2作为波特率发生器 2.波特率为115200bps@MCU频率22.1184MHz 3.串口接收数据使用完后,需要加UartEmp();函数清零接收数组。 4.接收数据为字符串时,...
  • 之前小沃写过关于go语言获取udp的代码,感觉延时还是比较高的,所以这次写一个用C实现的,用来接收UDP数据包,同时打印到终端,话不多说,上代码:#include#include#include#include#includecharbuff[32*1024];...
  • C语言 Socket TCP通信

    2020-05-31 21:46:48
    TCP简介 传输控制协议(TCP)是一种网络通信协议,旨在通过Internet发送数据包。TCP是OSI层中的传输层协议,用于通过传输和确保通过支持网络和Internet传递消息来在远程计算机之间创建连接。
  • #include #include #include #include #include int main(){struct ifreq ifr;struct ifconf ifc;char buf[2048];int success = 0;int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);if (sock == -1) {printf("so...
  • 任务要求: 1.以命令行形式运行:SendTCP source_ip source_port dest_ip dest_port; 2.头部参数自行设定,数据字段为“This is my homework of ...本系统要求使用C语言作为基本开发语言,并且开发工具为绿色软件,...
  • 以下是服务器的代码 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <strings.h> #include <sys/types.h> #include <sys/socket.h>... int sock
  • ping C语言实现

    2021-10-11 11:48:37
    } /********************** 函数名:Ping_unpack 功能:解析响应数据包、判断是否返回正常 参数:len 响应数据包长度 返回值:成功返回0,失败返回-1 **********************/ int Ping_unpack(int len) { double ...
  • 介绍网卡的接受和发送过程,对网卡驱动编写提供参考
  • socket编程是C语言编程中使用非常多的一种编程技术,下面我们就通过案例分析来了解一下,如何利用socket编程来实现网络通信协议。1、网络中进程之间如何通信?本地的进程间通信(IPC)有很多种方式,但可以总结为下面4...
  • C语言编程实现TCP/UDP/TFTP网络通信

    千次阅读 2022-04-15 23:08:56
    功能:与服务器建立连接 #include #include 参数: @sockfd: socket函数返回的文件描述符 @address: 服务器的网络信息结构体,用于标记连接到哪个服务器程序 @address_len:address长度 返回值:成功返回0,失败返回...
  • 《用C语言实现基于TCP协议的网络通讯》由会员分享,可在线阅读,更多相关《用C语言实现基于TCP协议的网络通讯(6页珍藏版)》请在人人文库网上搜索。1、用C#实现基于TCP协议的网络通讯TCP协议是一个基本的网络协议,...
  • 本文将介绍Linux系统中,基于RTL8139网卡驱动程序,是如何一步一步将接收到的数据包传送到内核的网络协议栈的。 下图展示了数据包(packet)如何进入内存,并被内核的网络模块开始处理: +-----+ | | Memroy +...
  • c语言Winpcap编程构造并接收解析arp包/*程序功能:1、构造arp包,并发送。程序参数顺序:源IP、目的IP、mac地址、flag2、获取网络中的ARP数据包,解析数据包的内容。程序参数:日志文件名winpacp中文技术文档(基本是...
  • 基本的数据类型有:int 4long 4short 2signed char 1unsigned char 1unsigned long 4unsigned short 2float 4double 8基本为:char 1字节short 2字节int 4字节long 4字节float 4字节double 8字节typedef struct{cha....
  • 本文的具体的内容包括以下几个部分:CC2530是符合802.15.4标准的无线收发芯片,但是本文并没有遵守802.15.4协议规则,在发送过程中忽略了网络ID、源地址和目标地址等参数,在接收的过程中禁止了帧过滤。通过发送和...
  • /*This program sends out one ARP packet with source/target IPand Ethernet hardware addresses suuplied by the user. Itcompiles and works on Linux and will probably work on anyUnix that has SOCK_PACKET....
  • 编程小白,代码可能比较冗长,请各位大佬指出不足 [*・ω・]运行现象思路程序源码(LINUX)1.head.h(头文件)2.datalink.c (存放着各种自定义函数接口)3.server.c(服务端)4.client.c(客户端)5.Makefile()代码中的不足之处...
  • c语言socket

    2022-04-10 20:27:09
    网络编程就是编写程序使两台联网的计算机相互交换数据。首先需要物理连接。如今大部分计算机都已经连接到互联网,因此不用担心这一点 在此基础上,只需要考虑如何编写数据传输程序。但实际上这点也不用愁,因为操作...
  • 这是一个简单的Socket程序例子,开发环境是vc6:新建工程 win32-控制台程序首先是TCPserver端:#include "stdafx.h"#include #include #pragma comment(lib,"ws2_32.lib")int main(int argc, char* argv[]){//初始化...
  • C语言可以做什么? 从最简单的、最熟悉的说起吧,毕竟我们在学校学习的时候,老师几乎都会让我们去开发: 一、C语言可以实现一些常见的应用 以下几个几乎是我们学习C语言到一定阶段之后必开发的一个小项目了,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,900
精华内容 1,160
关键字:

数据包收发c语言程序