嵌入式实验报告
题目: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 #include #include #include #include #include #include #include
#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
usage(argv[0]);
exit( 1 ); } if((clifd = socket(AF_INET,SOCK_STREAM,0))
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))
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)
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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include
#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
printf(\"Open ttyS%d failed\\n\",Comm);
return -1;
}
if( tcgetattr(ret, &g_oldtio)
{
printf(\"Get Com Parameter Error.\\n\");
return -1; }
for ( i= 0; 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) 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挂载
四、实验结果:
五、心得体会: