最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 正文

嵌入式实验部分函数代码

来源:动视网 责编:小OO 时间:2025-09-27 11:53:28
文档

嵌入式实验部分函数代码

实验十八网络编程(一)getaddrinfo()的使用【实验目的】通过实例来熟悉getaddrinfo()的用法。【实验代码】/*getaddrinfo.c*/#include#include#include#include#include#include#include#includeintmain(){structaddrinfohints,*res=NULL;intrc;memset(&hints,0,sizeof(hints));/*设置addrinfo结构体中各参数*/hints.a
推荐度:
导读实验十八网络编程(一)getaddrinfo()的使用【实验目的】通过实例来熟悉getaddrinfo()的用法。【实验代码】/*getaddrinfo.c*/#include#include#include#include#include#include#include#includeintmain(){structaddrinfohints,*res=NULL;intrc;memset(&hints,0,sizeof(hints));/*设置addrinfo结构体中各参数*/hints.a
实验十八  网络编程

(一)getaddrinfo()的使用

【实验目的】

通过实例来熟悉getaddrinfo()的用法。

【实验代码】

/* getaddrinfo.c */

#include

#include

#include

#include

#include

#include

#include

#include

int main()

{

    struct addrinfo hints, *res = NULL;

    int rc;

    

    memset(&hints, 0, sizeof(hints));

    /*设置addrinfo结构体中各参数 */

    hints.ai_flags = AI_CANONNAME;

    hints.ai_family = AF_UNSPEC;

    hints.ai_socktype = SOCK_DGRAM;

    hints.ai_protocol = IPPROTO_UDP;

    

    /*调用getaddinfo函数*/

    rc = getaddrinfo("localhost", NULL, &hints, &res);

    if (rc != 0) 

    {

        perror("getaddrinfo");

        exit(1);

    }

    else

    {

     printf("Host name is %s\\n", res->ai_canonname);

    }

    exit(0);

}

(二)socket编程实验

【实验目的】

POSIX中两种线程同步机制,分别是互斥锁和信号量来实现各个线程的顺序执行。

【实验代码】

/*server.c*/

#include

#include

#include

#include

#include

#include

#include

#include

#define PORT            4321

#define BUFFER_SIZE        1024

#define MAX_QUE_CONN_NM    5

int main()

{

    struct sockaddr_in server_sockaddr, client_sockaddr;

    int sin_size, recvbytes;

    int sockfd, client_fd;

    char buf[BUFFER_SIZE];

    

    /*建立socket连接*/

    if ((sockfd = socket(AF_INET,SOCK_STREAM,0))== -1)

    {

        perror("socket");

        exit(1);

    }

    printf("Socket id = %d\\n",sockfd);

    

    /*设置sockaddr_in 结构体中相关参数*/

    server_sockaddr.sin_family = AF_INET;

    server_sockaddr.sin_port = htons(PORT);

    server_sockaddr.sin_addr.s_addr = INADDR_ANY;

    bzero(&(server_sockaddr.sin_zero), 8);

    

    int i = 1;/* 使得重复使用本地地址与套接字进行绑定 */

    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));    

    

    /*绑定函数bind*/

    if (bind(sockfd, (struct sockaddr *)&server_sockaddr, sizeof(struct sockaddr))== -1)

    {

        perror("bind");

        exit(1);

    }

    printf("Bind success!\\n");

    

    /*调用listen函数*/

    if (listen(sockfd, MAX_QUE_CONN_NM) == -1)

    {

        perror("listen");

        exit(1);

    }

    printf("Listening....\\n");

    

    /*调用accept函数,等待客户端的连接*/

    if ((client_fd = accept(sockfd, (struct sockaddr *)&client_sockaddr, &sin_size)) == -1)

    {

        perror("accept");

        exit(1);

    }

    

    /*调用recv函数接收客户端的请求*/

    memset(buf , 0, sizeof(buf));

    if ((recvbytes = recv(client_fd, buf, BUFFER_SIZE, 0)) == -1)

    {

        perror("recv");

        exit(1);

    }

    printf("Received a message: %s\\n", buf);

    close(sockfd);

    exit(0);

}

/*client.c*/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define PORT    4321

#define BUFFER_SIZE 1024

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

{

    int sockfd, sendbytes;

    char buf[BUFFER_SIZE];

    struct hostent *host;

    struct sockaddr_in serv_addr;

    

if(argc < 3)

    {

        fprintf(stderr,"USAGE: ./client Hostname(or ip address) Text\\n");

        exit(1);

    }

    

    /*地址解析函数*/

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

    {

        perror("gethostbyname");

        exit(1);

    }

    

    memset(buf, 0, sizeof(buf));

    sprintf(buf, "%s", argv[2]);

    

    /*创建socket*/

    if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)

    {

        perror("socket");

        exit(1);

    }

    

    /*设置sockaddr_in 结构体中相关参数*/

    serv_addr.sin_family = AF_INET;

    serv_addr.sin_port = htons(PORT);

serv_addr.sin_addr = *((struct in_addr *)host->h_addr);

    bzero(&(serv_addr.sin_zero), 8);

    

    /*调用connect函数主动发起对服务器端的连接*/

    if(connect(sockfd,(struct sockaddr *)&serv_addr, sizeof(struct sockaddr))== -1)

    {

        perror("connect");

        exit(1);

    }

    

    /*发送消息给服务器端*/

    if ((sendbytes = send(sockfd, buf, strlen(buf), 0)) == -1)

    {

        perror("send");

        exit(1);

    }

    close(sockfd);

    exit(0);

}

【实验结果】

编译并运行程序,查看实验结果。

先启动服务器端,再启动客户端。注意服务器端和客户端可以分别是宿主机和目标机,只要配置好IP地址,既可以确保通信。

(三)fctnl()多路复用

【实验目的】

使用fcntl()来解决多路复用。

【实验代码】

/* net_fcntl.c */

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define PORT                1234

#define MAX_QUE_CONN_NM        5

#define BUFFER_SIZE            1024

int main()

{

    struct sockaddr_in server_sockaddr, client_sockaddr;

    int sin_size, recvbytes, flags;

    int sockfd, client_fd;

    char buf[BUFFER_SIZE];    

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

    {

        perror("socket");

        exit(1);

    }    

    server_sockaddr.sin_family=AF_INET;

    server_sockaddr.sin_port=htons(PORT);

    server_sockaddr.sin_addr.s_addr=INADDR_ANY;

    bzero(&(server_sockaddr.sin_zero),8);

    

    int i = 1;/* 使得重复使用本地地址与套接字进行绑定 */

    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));

    

    if (bind(sockfd, (struct sockaddr *)&server_sockaddr, sizeof(struct sockaddr)) == -1)

    {

        perror("bind");

        exit(1);

    }

    

    if(listen(sockfd,MAX_QUE_CONN_NM)== -1)

    {

        perror("listen");

        exit(1);

    }

    printf("Listening....\\n");

    

    /* 调用fcntl函数设置非阻塞属性 */

    flags = fcntl(sockfd, F_GETFL);

if (flags < 0 || fcntl(sockfd, F_SETFL, flags|O_NONBLOCK) < 0)

    {

        perror("fcntl");

        exit(1);

    }

        

     while(1)

     {

         sin_size = sizeof(struct sockaddr_in);

      if ((client_fd = accept(sockfd, (struct sockaddr*)&client_sockaddr, &sin_size)) < 0)

         {

             perror("accept");

             exit(1);

         }

         

      if ((recvbytes = recv(client_fd, buf, BUFFER_SIZE, 0)) < 0)

         {

             perror("recv");

             exit(1);

         }

         

         printf("Received a message: %s\\n", buf);

  } /*while*/

  

  close(client_fd);

  exit(1);

}

【实验结果】

编译并运行程序,查看实验结果。

当accept()的资源不可用时,程序就会自动返回。

(四)select()多路复用

【实验目的】

服务器端代码使用select()函数来实现,客户端程序与实验(二)相同,仅仅加入一行sleep()函数,使得客户端进程等待几秒再结束。

【实验代码】

/* net_select.c */

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define PORT                4321

#define MAX_QUE_CONN_NM            5

#define MAX_SOCK_FD            FD_SETSIZE

#define BUFFER_SIZE            1024

int main()

{

    struct sockaddr_in server_sockaddr, client_sockaddr;

    int sin_size, count;

    fd_set inset, tmp_inset;

    int sockfd, client_fd, fd;

    char buf[BUFFER_SIZE];

    

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

    {

        perror("socket");

        exit(1);

    }

    

    server_sockaddr.sin_family = AF_INET;

    server_sockaddr.sin_port = htons(PORT);

    server_sockaddr.sin_addr.s_addr = INADDR_ANY;

    bzero(&(server_sockaddr.sin_zero), 8);

    

    int i = 1;/* 使得重复使用本地地址与套接字进行绑定 */

    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));

    if (bind(sockfd, (struct sockaddr *)&server_sockaddr, sizeof(struct sockaddr)) == -1)

    {

        perror("bind");

        exit(1);

    }

    

    if(listen(sockfd, MAX_QUE_CONN_NM) == -1)

    {

        perror("listen");

        exit(1);

    }

    printf("listening....\\n");

    

    /*将调用socket函数的描述符作为文件描述符*/

    FD_ZERO(&inset);

    FD_SET(sockfd, &inset);

    

    while(1)

    {

        tmp_inset = inset;

        sin_size=sizeof(struct sockaddr_in);

        memset(buf, 0, sizeof(buf));

        

        /*调用select函数*/

        if (!(select(MAX_SOCK_FD, &tmp_inset, NULL, NULL, NULL) > 0))

        {

            perror("select");

            close(sockfd);

            exit(1);

        }

        

     for (fd = 0; fd < MAX_SOCK_FD; fd++)

        {

         if (FD_ISSET(fd, &tmp_inset) > 0)

            {

                if (fd == sockfd)

                { /* 服务端接收客户端的连接请求 */

                    if ((client_fd = accept(sockfd, (struct sockaddr *)&client_sockaddr, &sin_size))== -1)

                    {

                        perror("accept");

                        exit(1);

                    }

                    FD_SET(client_fd, &inset);

                    printf("New connection from %d(socket)\\n", client_fd);

                }

                else /* 处理从客户端发来的消息 */

                {

                    if ((count = recv(fd, buf, BUFFER_SIZE, 0)) > 0)

                    {

                        printf("Received a message from %d: %s\\n", fd, buf);

                    }

                    else        

                    {

                        close(fd);

                        FD_CLR(fd, &inset);

                        printf("Client %d(socket) has left\\n", fd);

                    }                        

                }        

            } /* end of if FD_ISSET*/ 

        } /* end of for fd*/

    } /* end if while while*/

    

    close(sockfd);

    exit(0);

}

【实验结果】

先启动服务器端,再反复运行客户端程序,观察运行结果。

(五)NTP协议实现

【实验目的】

通过实现NTP协议的练习,进一步掌握Linux网络编程,并且提高协议的分析与实现能力,为参与完成综合性项目打下良好的基础。

【实验代码】

/* ntp.c */

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define NTP_PORT                123

#define TIME_PORT                37

#define NTP_SERVER_IP        "210.72.145.44"

#define NTP_PORT_STR        "123"

#define NTPV1               "NTP/V1"

#define NTPV2               "NTP/V2"

#define NTPV3               "NTP/V3"

#define NTPV4               "NTP/V4"

#define TIME                "TIME/UDP"

#define NTP_PCK_LEN 48

#define LI 0

#define VN 3

#define MODE 3

#define STRATUM 0

#define POLL 4 

#define PREC -6

#define JAN_1970    0x83aa7e80  /* 从1900年到1970年之间的时间秒数 */

#define NTPFRAC(x) (4294 * (x) + ((1981 * (x)) >> 11))

#define USEC(x)     (((x) >> 12) - 759 * ((((x) >> 10) + 32768) >> 16))

typedef struct _ntp_time 

{

    unsigned int coarse;

    unsigned int fine;

} ntp_time;

struct ntp_packet

{

    unsigned char leap_ver_mode;

    unsigned char startum; 

    char poll;

    char precision;

    int  root_delay;

    int  root_dispersion;

    int reference_identifier;

    ntp_time reference_timestamp;

    ntp_time originage_timestamp;

    ntp_time receive_timestamp;

    ntp_time transmit_timestamp;

};

char protocol[32];

/*构建NTP协议包*/

int construct_packet(char *packet)

{

    char version = 1;

    long tmp_wrd;

    int port;

    time_t timer;

    strcpy(protocol, NTPV3);

        

    /*判断协议版本*/

    if(!strcmp(protocol, NTPV1)||!strcmp(protocol, NTPV2)||!strcmp(protocol, NTPV3)||!strcmp(protocol, NTPV4))

    {

        memset(packet, 0, NTP_PCK_LEN);

        port = NTP_PORT;

        /*设置16字节的包头*/

        version = protocol[6] - 0x30;

     tmp_wrd = htonl((LI << 30)|(version << 27)|(MODE << 24)|(STRATUM << 16)|(POLL << 8)|(PREC & 0xff));

        memcpy(packet, &tmp_wrd, sizeof(tmp_wrd));

        

        /*设置Root Delay、Root Dispersion和Reference Indentifier */

        tmp_wrd = htonl(1<<16);

        memcpy(&packet[4], &tmp_wrd, sizeof(tmp_wrd));

        memcpy(&packet[8], &tmp_wrd, sizeof(tmp_wrd));

        

        /*设置Timestamp部分*/

        time(&timer);

        tmp_wrd = htonl(JAN_1970 + (long)timer);

        memcpy(&packet[40], &tmp_wrd, sizeof(tmp_wrd)); /*Transmit Timestamp coarse*/

        tmp_wrd = htonl((long)NTPFRAC(timer));

        memcpy(&packet[44], &tmp_wrd, sizeof(tmp_wrd)); /*Transmit Timestamp fine*/

        return NTP_PCK_LEN;

    }

    else if (!strcmp(protocol, TIME))/* "TIME/UDP" */

    {

        port = TIME_PORT;

        memset(packet, 0, 4);

        return 4;

    }

    

    return 0;

}

/*获取NTP时间*/

int get_ntp_time(int sk, struct addrinfo *addr, struct ntp_packet *ret_time)

{

    fd_set pending_data;

    struct timeval block_time;

    char data[NTP_PCK_LEN * 8];

int packet_len, data_len = addr->ai_addrlen, count=0, result, i, re;    

    if (!(packet_len = construct_packet(data)))

    {

        return 0;

    }

    

    /*客户端给服务器端发送NTP协议数据包*/

    if ((result = sendto(sk, data, packet_len, 0, addr->ai_addr, data_len)) < 0)

    {

        perror("sendto");

        return 0;

    }

    

    /*调用select函数,并设定超时时间为1s*/

    FD_ZERO(&pending_data);

    FD_SET(sk, &pending_data);

    block_time.tv_sec=10;

    block_time.tv_usec=0;

if (select(sk + 1, &pending_data, NULL, NULL, &block_time) > 0)

    {

        /*接收服务器端的信息*/

        if ((count = recvfrom(sk, data, NTP_PCK_LEN * 8, 0, addr->ai_addr, &data_len)) < 0)

        {

            perror("recvfrom");

            return 0;

        }

        

        if (protocol == TIME)

        {

         memcpy(&ret_time->transmit_timestamp, data, 4);

            return 1;

        }

     else if (count < NTP_PCK_LEN)

        {

            return 0;

        }

        

     ret_time->leap_ver_mode = ntohl(data[0]);

     ret_time->startum = ntohl(data[1]);

     ret_time->poll = ntohl(data[2]);

     ret_time->precision = ntohl(data[3]);

     ret_time->root_delay = ntohl(*(int*)&(data[4]));

     ret_time->root_dispersion = ntohl(*(int*)&(data[8]));

     ret_time->reference_identifier = ntohl(*(int*)&(data[12]));

     ret_time->reference_timestamp.coarse = ntohl(*(int*)&(data[16]));

     ret_time->reference_timestamp.fine = ntohl(*(int*)&(data[20]));

     ret_time->originage_timestamp.coarse = ntohl(*(int*)&(data[24]));

     ret_time->originage_timestamp.fine = ntohl(*(int*)&(data[28]));

     ret_time->receive_timestamp.coarse = ntohl(*(int*)&(data[32]));

     ret_time->receive_timestamp.fine = ntohl(*(int*)&(data[36]));

     ret_time->transmit_timestamp.coarse = ntohl(*(int*)&(data[40]));

     ret_time->transmit_timestamp.fine = ntohl(*(int*)&(data[44]));

        return 1;        

    } /* end of if select */    

    return 0;

}

int set_local_time(struct ntp_packet * pnew_time_packet)

{

    struct timeval tv;

tv.tv_sec = pnew_time_packet->transmit_timestamp.coarse - JAN_1970;

tv.tv_usec = USEC(pnew_time_packet->transmit_timestamp.fine);

    return settimeofday(&tv, NULL);

}

int main()

{

    int sockfd, rc;

    struct addrinfo hints, *res = NULL;

    struct ntp_packet new_time_packet;

        

    memset(&hints, 0, sizeof(hints));

    hints.ai_family = AF_UNSPEC;

    hints.ai_socktype = SOCK_DGRAM;

    hints.ai_protocol = IPPROTO_UDP;

    

    /*调用getaddrinfo函数,获取地址信息*/

    rc = getaddrinfo(NTP_SERVER_IP, NTP_PORT_STR, &hints, &res);

    if (rc != 0) 

    {

        perror("getaddrinfo");

        return 1;

    }

    

    sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);

if (sockfd <0 )

    {

        perror("socket");

        return 1;

    }

        

    /*调用取得NTP时间函数*/

    if (get_ntp_time(sockfd, res, &new_time_packet))

    {

        /*调整本地时间*/

        if (!set_local_time(&new_time_packet))

        {

            printf("NTP client success!\\n");

        }

    }

    

    close(sockfd);

    return 0;

}

【实验结果】

先用date命令修改一下系统时间,再运行程序,运行之后查看系统时间,会发现已经恢复准确的系统时间了。

文档

嵌入式实验部分函数代码

实验十八网络编程(一)getaddrinfo()的使用【实验目的】通过实例来熟悉getaddrinfo()的用法。【实验代码】/*getaddrinfo.c*/#include#include#include#include#include#include#include#includeintmain(){structaddrinfohints,*res=NULL;intrc;memset(&hints,0,sizeof(hints));/*设置addrinfo结构体中各参数*/hints.a
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top