嵌入式串口和网络编程实验报告

   嵌入式实验报告

              

                                   

                                                 

              

     题目:linux串口和网络编程

一、实验目的:

        1、强化本学期所学的相关的内容。

 2、掌握串口相关设置。

 3、强化基于TCP网络传输的三次握手。

 4、自学Linux线程的使用。

二、实验内容:

 本试验基于server和client的透明传输来实现类似于QQ的聊天功能。

三、实验过程:

        1、linux开发环境的建立

        2、嵌入式linux系统的搭建

        1>BootLoader的移植

        2>linux系统的裁剪与移植

          Linux内核裁剪

        

      ./make_image生成自己的uImage2638

上电验证:

3>根文件系统的移植

修改hostname为:whmtt

./mkcramfsdisk_new 生成rootfs_new.cramfs

大小从老师给的40000到37b00(因为有的没有用到,大小变小了):

上电验证:

     3、客服端编程client.c

       相关代码:

#include <stdio.h> 

#include <sys/socket.h> 

#include <unistd.h> 

#include <sys/types.h> 

#include <netinet/in.h>  

#include <stdlib.h>  

#include <strings.h>

#include <string.h>

#define  SERVER_PORT 20000                    //设置服务端口

#define  CLIENT_PORT ((20001+rand())%65536)   //设置客户端端口(随机)

#define  BUFFER_SIZE 256

#define  LENGTH_OF_LISTEN_QUEUE 10            //可窃听队列长为10

#define  WELCOME_MESSAGE "welcome to connect the server." 

void usage(char* name) 

    printf( "usage: %s IpAddr\n " ,name); 

struct sockaddr_in servaddr,cliaddr;

int servfd,clifd,length=0;

struct sockaddr_in servaddr,cliaddr;

socklen_t socklen=sizeof(servaddr);

char buf[BUFFER_SIZE],buf2[BUFFER_SIZE];

pthread_t tidp,tidp2;

int pth;

int runflag=0;

void *Thread1(void *arg)   /*等待runflag为1,当为1时清空buf,

                            同时接收来自server的数据并输出。

                            但当没有清空,则break.*/

{

    while(runflag){

        memset(buf,0,BUFFER_SIZE);    

        length=recv(clifd,buf,BUFFER_SIZE,0);

        if(strstr(buf,"$")>0){runflag=0;printf("stop!\n");break;}

        if(length>0) printf("from server:%s",buf);

        }

}

void *Thread2(void *arg)  /*等待发送数据给Server*/

{

    printf("Please input your words to Server:--$ to stop\n");

    while(runflag){

        memset(buf2,0,BUFFER_SIZE);

        scanf("%s",buf2);

        send(clifd,buf2,strlen(buf2),0);

        if(strstr(buf2,"$")>0){runflag=0;printf("stop!\n");break;}

        }

}

int main(int argc, char** argv) 

{  

    if(argc < 2 ) 

    { 

        usage(argv[0]); 

        exit( 1 ); 

    }  

    if((clifd = socket(AF_INET,SOCK_STREAM,0))  <   0 )  //用tcp定义socket

    {

        printf( " create socket error!\n " ); 

        exit( 1 ); 

    }  

    srand(time(NULL)); // initialize random generator  

   

    bzero( & cliaddr, sizeof (cliaddr)); 

    cliaddr.sin_family = AF_INET; 

    cliaddr.sin_port   = htons(CLIENT_PORT); 

    cliaddr.sin_addr.s_addr = htons(INADDR_ANY);

   

    if(bind(clifd,(struct sockaddr* )&cliaddr,sizeof(cliaddr)) < 0 ) 

    {

        printf( "bind to port %d failure!\n " ,CLIENT_PORT); 

        exit( 1 ); 

    }//绑定的目的是让其端口是随机的,否则端口是自增1

     //一般情况下client端不用绑定

   

    bzero(&servaddr, sizeof(servaddr));     

    servaddr.sin_family = AF_INET; 

    inet_aton(argv[1], &servaddr.sin_addr); 

    servaddr.sin_port = htons(SERVER_PORT); 

      

    if(connect(clifd,( struct  sockaddr *)&servaddr, socklen) < 0) 

    { 

        printf( "can't connect to %s!\n", argv[1]); 

        exit(1); 

    }  

   

        runflag=1;

            pth=pthread_create(&tidp,NULL,Thread1,NULL);

            if(pth!=0){printf("error!");return -1;}

            pth=pthread_create(&tidp2,NULL,Thread2,NULL);

            if(pth!=0){printf("error!");return -1;}

            pthread_detach(tidp);

            pthread_detach(tidp2);

            while(runflag){;}

            close(clifd);

        return 0;

}

       4、服务端server.c编写

          相关代码:

#include <stdio.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <unistd.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <stdlib.h>

#include <time.h>

#include <string.h>

#include <strings.h>

#include <sys/ioctl.h>

#include <fcntl.h>

#include <termios.h>

#include <stdlib.h>

#include <errno.h>

#include <sys/time.h>

#include <linux/rtc.h>

#include <pthread.h>

#define COM0        0

#define BLOCK_MODE  1

#define NONBLK_MODE 0

#define SERVER_PORT 20000

#define LENGTH_OF_LISTEN_QUEUE 10

#define QUEUE 20

#define BUFFER_SIZE 256

#define  WELCOME_MESSAGE "welcome to connect the server."

static struct termios g_newtio,g_oldtio;

static int speed_arr[] =

{

 B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300,

 B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300,

};

static int name_arr[] =

{

 115200, 57600, 38400,  19200,  9600,  4800,  2400,  1200,  300,

 115200, 57600, 38400,  19200,  9600,  4800,  2400,  1200,  300,

};

int Init_COM(int Comm,int Baudrate,int Parity,int Stopbit,int Flagblock)

{

    int ret,i;

    char dev_buf[16];

       

    if(Comm > 3)

    {

        printf("Com%d not exist\n",Comm); 

        return -1;

    }

   

    memset(dev_buf,0x00,sizeof(dev_buf));

    sprintf(dev_buf,"/dev/ttyS%d",Comm);

   

    if(Flagblock)

    {

        ret = open(dev_buf, O_RDWR | O_NOCTTY );//以默认阻塞方式打开

    }

    else

    {

        ret = open(dev_buf, O_RDWR | O_NOCTTY | O_NONBLOCK); //以非阻塞方式打开

    }

   

    if(ret < 0)

    {

        printf("Open ttyS%d failed\n",Comm);

        return -1;

    }

       

    if( tcgetattr(ret, &g_oldtio) < 0 )//保存原先的端口

    {

        printf("Get Com Parameter Error.\n"); 

        return -1;

    }

   

    for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++)

    {

        if(Baudrate == name_arr[i])

        {    

           cfsetispeed(&g_newtio,speed_arr[i]);/*设置输入输出波特率*/

           cfsetospeed(&g_newtio,speed_arr[i]);

           break;

        } 

    }

   

    if(i>=sizeof(speed_arr) / sizeof(int))

    {

            printf("Unsupported Speed!\n");

        return -1;

    }

       

    switch (Parity)

    {

        case 'n':

        case 'N':   

            g_newtio.c_cflag &= ~PARODD; 

            g_newtio.c_cflag &= ~PARENB; 

        break; 

        case 'o':  

        case 'O':    

                g_newtio.c_cflag |= PARENB;   

            g_newtio.c_cflag |= PARODD;    //奇校验

        break; 

        case 'e': 

        case 'E':  

            g_newtio.c_cflag |= PARENB;   //偶校验

            g_newtio.c_cflag &= ~PARODD;   

        break;

   

        default:  

            printf("Unsupported Parity\n");   

        return -1; 

    }  

   

   

    switch(Stopbit) //设置停止校验位是为2,否为1.

    {

        case 1:

            g_newtio.c_cflag &= ~CSTOPB;

        break;

        case 2:

            g_newtio.c_cflag |= CSTOPB;

        break;

        default:

            printf("Unsupported Stopbit!\n"); 

            return -1;

    }

    g_newtio.c_iflag = 0;          

    g_newtio.c_oflag = 0;          

    g_newtio.c_lflag  = 0;         

   

    g_newtio.c_cc[VTIME] = 1;   //最大等待时间为1*100ms  

    g_newtio.c_cc[VMIN]  = 1;   //最小读数为1 

   

    g_newtio.c_iflag &= ~INPCK;    

    g_newtio.c_cflag &= ~CRTSCTS;  

    g_newtio.c_cflag &= ~CSIZE;//设置数据位

    g_newtio.c_cflag |= CS8;   //  

    g_newtio.c_cflag |= CLOCAL;  

    g_newtio.c_cflag |= CREAD;     

   

    if( tcsetattr(ret, TCSANOW, &g_newtio) != 0 ) //激活设置

    {

        printf("Set Com Parameter Error!\n");

        return -1;

    }

   

    tcflush (ret, TCIOFLUSH);   //刷新输入输出缓存

    return ret;

}

//以上为套接字的相关定义

//一下类似与client一样设置数据接收和发送。

void RestoreComConfiguration(int fd,struct termios *ptios)

{

    if( tcsetattr(fd, TCSANOW, ptios) != 0 )

    {

        printf("Restore Com Parameter Error!\n");

    }

}

int fd;char buf[1024],buf2[1024];

int servfd,clifd;

struct sockaddr_in servaddr,cliaddr;

int runflag=0;

void *Thread1(void *arg)

{

    printf("Please input your words to Server:--$ to stop\n");

    while(runflag){

        memset(buf,0,BUFFER_SIZE);

        read(fd,buf,1024);

        send(clifd,buf,strlen(buf),0);

        if(strstr(buf,"$")>0){runflag=0;printf("stop!\n");break;}

        }

}

void *Thread2(void *arg)

{

    int length=0;

    while(runflag){char

 stdstr[1024]="from client:";

               memset(buf2,0,BUFFER_SIZE);

               length=recv(clifd,buf2,1024,0);

                      

        if(length>0)

                {

        strcat(stdstr,buf2);strcat(stdstr,"\n");

        if(strstr(buf2,"$")>0)

            {runflag=0;printf("stop!\n");break;}

        write(fd,stdstr,strlen(stdstr));

        }

              }

       

}

void socket_init(void)

{

    if((servfd=socket(AF_INET,SOCK_STREAM,0))<0)

    {printf("create socket error!\n");

    exit(1);

    }

    bzero(&servaddr,sizeof(servaddr));

    servaddr.sin_family=AF_INET;

    servaddr.sin_port=htons(SERVER_PORT);

    servaddr.sin_addr.s_addr=htons(INADDR_ANY);

    if(bind(servfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)

    {printf("bind to port %d failure!\n",SERVER_PORT);

    exit(1);

    }

    if(listen(servfd,QUEUE)<0)

    {printf("call listen failure!\n");

    exit(1);

    }

    socklen_t length=sizeof(cliaddr);

    clifd=accept(servfd,(struct sockaddr*)&cliaddr,&length);

    if(clifd<0){ printf("error comes when call accept!\n");

    exit(1);}

}

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

{

    fd = Init_COM(COM0,115200,'N',1,BLOCK_MODE);

    socket_init();

    pthread_t tidp,tidp2;

    int pth;

    if(fd >= 0) RestoreComConfiguration(fd,&g_oldtio);

        runflag=1;

        pth=pthread_create(&tidp,NULL,Thread1,NULL);

        if(pth!=0){printf("error!");return -1;}

        pth=pthread_create(&tidp2,NULL,Thread2,NULL);

        if(pth!=0){printf("error!");return -1;}

        pthread_detach(tidp);

        pthread_detach(tidp2);

        while(runflag){;}

        close(clifd);close(fd);close(servfd);//全部关闭

        return 0;

}

      编译结果:

       5、nfs挂载

四、实验结果:

五、心得体会:

相关推荐