嵌入式技术及应用-【Ubuntu】利用TCP Socket实现PC机与目标板的通讯

一、作业要求

1、利用TCP Socket实现PC机与目标板的通讯,目标板作为服务端,服务端按要求给多个个客户端同时传送不同的文件(可以使用多线程机制、非阻塞或异步式处理)。

作业要求:1)交电子文档,需要源代码。

  1. 上机演示

2、试找一个字符型驱动程序实例进行分析。

作业要求:1)交电子文档,需要源代码。

二、作业原理与内容

1、利用TCP Socket实现PC机与目标板的通讯,目标板作为服务端,服务端按要求给多个个客户端同时传送不同的文件(可以使用多线程机制、非阻塞或异步式处理)。

作业要求:1)交电子文档,需要源代码。

  1. 上机演示

2、试找一个字符型驱动程序实例进行分析。

作业要求:1)交电子文档,需要源代码。

三、实验软硬件环境

虚拟机软件、一台计算机、开发板

四、作业过程(步骤、记录、数据、分析)

 按步骤依次写出程序、运行结果等(可截屏)

1、利用TCP Socket实现PC机与目标板的通讯,目标板作为服务端,服务端按要求给多个个客户端同时传送不同的文件(可以使用多线程机制、非阻塞或异步式处理)。

服务器server端代码:

#include <stdio.h>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <pthread.h>
#define portnum 12345
#define FILE_SIZE 500 
#define BUFFER_SIZE 1024
void *net_thread(void * fd);
int main()
{
	//初始化套接字
	int server_fd=socket(AF_INET,SOCK_STREAM,0);
	if(-1==server_fd)
	{
		perror("socket");
		exit(1);
	}
	//绑定端口和ip;
	struct sockaddr_in server_addr; //struct sockaddr_in为结构体类型 ,server_addr为定义的结构体   
	server_addr.sin_family=AF_INET;   //Internet地址族=AF_INET(IPv4协议) 
	server_addr.sin_port=htons(portnum);  //将主机字节序转化为网络字节序 ,portnum是端口号
	(server_addr.sin_addr).s_addr=htonl(INADDR_ANY); //IP地址
	if(-1==bind(server_fd,(struct sockaddr *)&server_addr,sizeof(server_addr))) //套接字与端口绑定
	{
		perror("bind");
		exit(6);
	}
	//开启监听
	if(-1==listen(server_fd,5)) //5是最大连接数,指服务器最多连接5个用户
	{
		perror("listen");
		exit(7);
	}
	while(1)
	{
		struct sockaddr_in client_addr;
		int size=sizeof(client_addr);
		int new_fd=accept(server_fd,(struct sockaddr *)&client_addr,&size);  
//server_fd服务器的socket描述字,&client_addr指向struct sockaddr *的指针,&size指向协议地址长度指针
		if(-1==new_fd)
		{
			perror("accept");
			continue;       //进行下一次循环
		}
		printf("accept client ip:%s:%d\n",inet_ntoa(client_addr.sin_addr),client_addr.sin_port);
		//inet_ntoa将一个十进制网络字节序转换为点分十进制IP格式的字符串。
		printf("new_fd=%d\n",new_fd);
		// 打开文件,存入客户端的文件描述符
	    FILE *file_fp = fopen("01.file_fp", "w+"); 
        if(NULL == file_fp) 
        { 
             printf(" open 01.file_fp failure\n" ); 
             exit(1); 
        } 
	    else 
	    {
		     int a=new_fd;
		     fprintf(file_fp,"%d\n",new_fd);
		     fclose(file_fp);
	    }
		int pthread_id;
		int ret = pthread_create((pthread_t *)&pthread_id,NULL,net_thread,(void *)&new_fd);
		if(-1==ret)
		{
			perror("pthread_create");
			close(new_fd);
			continue;
		}
	}
	close(server_fd);
	return 0;
}
void *net_thread(void * fd)
{
	pthread_detach(pthread_self()); //线程分离
	int new_fd=*((int *)fd);
	int file2_fp;
	
	while(1)
	{
		// recv函数接收数据到缓冲区buffer中 
        char buffer[BUFFER_SIZE];
        memset( buffer,0, sizeof(buffer) );		
        if(read(new_fd, buffer, sizeof(buffer)) < 0) 
        { 
           perror("Server Recieve Data Failed:"); 
           break; 
        } 
        // 然后从buffer(缓冲区)拷贝到file_name中 
        char file_name[FILE_SIZE]; 
		memset( file_name,0, sizeof(file_name) );	
        strncpy(file_name, buffer, strlen(buffer)>FILE_SIZE?FILE_SIZE:strlen(buffer)); 
		memset( buffer,0, sizeof(buffer) );
        printf("%s\n", file_name); 
		
		if( strcmp(file_name,"null")==0 )
	    {
		   break;
		   close(new_fd);
	    }
		  // 打开文件并读取文件数据 
         file2_fp = open(file_name,O_RDONLY,0777); 
         if(file2_fp<0) 
         { 
            printf("File:%s Not Found\n", file_name); 
         } 
         else 
         { 
            int length = 0; 
			memset( buffer,0, sizeof(buffer) );
            // 每读取一段数据,便将其发送给客户端,循环直到文件读完为止 
            while( (length = read(file2_fp, buffer, sizeof(buffer))) > 0  )    
            {   
                if( write(new_fd, buffer, length) < 0) 
                { 
                    printf("Send File:%s Failed.\n", file_name); 
                    break; 
                } 
                memset( buffer,0, sizeof(buffer) );
            } 
              // 关闭文件 
              close(file2_fp); 
              printf("File:%s Transfer Successful!\n", file_name); 
         }   
	}
	close(new_fd);
}

   

客户端client代码:

#include <stdio.h>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#define portnum 12345
#define FILE_SIZE 500 
#define BUFFER_SIZE 1024
int sendfile(int sockfd);
int main()
{
	char name[30]={0};
	printf("请输入服务器的主机名或者ip\n");
	scanf("%s",name);
	struct hostent *h;
	//获取服务器信息
	h=gethostbyname(name);
	if(NULL==h)
	{
		perror("geyhostbyname");
		exit(1);
	}
	//初始化套接字
	int sockfd=socket(AF_INET,SOCK_STREAM,0);
	if(-1==sockfd)
	{
		perror("socket");
		exit(2);
	}
	struct sockaddr_in server_addr;
	server_addr.sin_family=AF_INET;
	server_addr.sin_port=htons(portnum);
	server_addr.sin_addr=*((struct in_addr *)h->h_addr_list[0]);
	if(-1==connect(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr)))
	{
		perror("connect");
		exit(3);
	}
	while(1)
	{
	   sendfile(sockfd);
    }
	return 0;	
}
int sendfile(int sockfd)
{
    // 输入文件名 并放到缓冲区buffer中等待发送 
	int file_fp;
    char file_name[FILE_SIZE];  
	memset( file_name,0, sizeof(file_name) );
    printf("Please Input File Name On Server:   "); 
    scanf("%s", file_name); 
    char buffer[BUFFER_SIZE]; 
    memset( buffer,0, sizeof(buffer) );
    strncpy(buffer, file_name, strlen(file_name)>sizeof(buffer)?sizeof(buffer):strlen(file_name)); 
    // 向服务器发送buffer中的数据 
    if(write(sockfd, buffer, sizeof(buffer)) < 0) 
    { 
       perror("Send File Name Failed:"); 
       exit(1); 
    } 
	if( strcmp(file_name,"null")==0 )
	{
		exit(1);
		close(sockfd);
	}	
	 // 打开文件,准备写入 
     file_fp = open(file_name,O_CREAT|O_RDWR,0777); 
     if( file_fp<0 ) 
     { 
         printf("File:\t%s Can Not Open To Write\n", file_name); 
         exit(1); 
     } 
     // 从服务器接收数据到buffer中 
     // 每接收一段数据,便将其写入文件中,循环直到文件接收完并写完为止 
    int length = 0; 
	memset( buffer,0, sizeof(buffer) );
    while((length = read(sockfd, buffer, sizeof(buffer))) > 0) 
    { 
        if( write( file_fp, buffer, length ) < length) 
        { 
            printf("File:\t%s Write Failed\n", file_name); 
            break; 
        } 
		if(length < sizeof(buffer))
		{
			break;
		}
        memset( buffer,0, sizeof(buffer) );
    } 
	// 接收成功后,关闭文件,关闭socket 
     printf("Receive File:\t%s From Server IP Successful!\n", file_name); 
     close(file_fp); 	
}

②测试server与client的连通性

③从服务器传送xxx文件到客户端,客户端从接收到文件xxx,如下图所示:

2、试找一个字符型驱动程序实例进行分析。

用gcc编写出wwcom_writer可执行文件

/* com_writer.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <termios.h>
#include "uart_api.h"
//#include "uart_apiarm.h"
#define BUFFER_SIZE 1024
#define HOST_COM_PORT 1
int main(void) 
{
	int fd;
	char buff[BUFFER_SIZE];
	if((fd = open_port(HOST_COM_PORT)) < 0) /* 打开串口 */
	{
		perror("open_port");
		return 1;
	}
          //printf("ok");	
	if(set_com_config(fd, 115200, 8, 'N', 1) < 0) /* 配置串口 */
	{
		perror("set_com_config");
		return 1;
	}	
	do
	{
		printf("Input some words(enter 'quit' to exit):");
		memset(buff, 0, BUFFER_SIZE);
		if (fgets(buff, BUFFER_SIZE, stdin) == NULL)
		{
			perror("fgets");
			break;
		}
		if(write(fd, buff, strlen(buff))>0)
                   {
			printf("The sended words are : %s", buff);
		}
           printf("ok\n");	 
	} while(strncmp(buff, "quit", 4));
do
    //while(1)
	{
		memset(buff, 0, BUFFER_SIZE);
           printf("start read\n");
		if (read(fd, buff, BUFFER_SIZE) > 0)
                    //read(fd, buff, BUFFER_SIZE);
		{
			printf("The received words are : %s\n", buff);
                         printf("success\n");
		}
               // else 
              // {
		//	printf("receive not success");
		//}
                sleep(2);
	} while(strncmp(buff, "ok", 2));
  	close(fd);
  	return 0;
}

用arm-linux-gcc编译出wwcom_reader可执行文件

/* com_reader.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <termios.h>
#include "uart_apiarm.h"
//#include "uart_api.h"
#define BUFFER_SIZE 1024
#define TARGET_COM_PORT 1
int main(void) 
{
	int fd;
	char buff[BUFFER_SIZE];
	if((fd = open_port(TARGET_COM_PORT)) < 0) /* 打开串口 */
	{
		perror("open_port");
		return 1;
	}
        printf("ok\n");
	if(set_com_config(fd, 115200, 8, 'N', 1) < 0) /* 配置串口 */
	{
		perror("set_com_config");
		return 1;
	}
        printf("wei\n");
	do
    //while(1)
	{
		memset(buff, 0, BUFFER_SIZE);
           printf("start read\n");
		if (read(fd, buff, BUFFER_SIZE) > 0)
                    //read(fd, buff, BUFFER_SIZE);
		{
			printf("The received words are : %s\n", buff);
                         printf("success\n");
		}
               // else 
              // {
		//	printf("receive not success");
		//}
                sleep(2);
	} while(strncmp(buff, "quit", 4));
//while(1);
       write(fd, "ok", 2);
       printf("success ok\n");   
  	close(fd);
  	return 0;
}

ping检查虚拟机与开发板的连通性

./wwcom_writer./wwcom_reader分别执行即可实现字符串的写入和读取

思考题:

  1. 用的是什么方式控制多个客户端连接?

答:用多线程方式

  1. 线程在网络通信哪个阶段创建的?

答:在接收阶段

  1. 服务器和客户端的 IP 地址怎么配置?

答:都是配置服务器的 IP 地址

总结:

1、了解linux环境下串行程序设计的方法,设备文件系统的使用方法;

2、掌握终端的主要属性及设置方法;

3、了解主机与开发板的连接和通信(包括串口和网络连接、主机与开发板之间的文件传输)。

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Ubuntu利用rabbitmq实现通信,需要以下步骤: 1. 安装rabbitmq-server和rabbitmq-client ``` sudo apt-get update sudo apt-get install rabbitmq-server rabbitmq-client ``` 2. 配置rabbitmq-server 打开rabbitmq配置文件/etc/rabbitmq/rabbitmq.conf,在末尾添加以下内容: ``` listeners.tcp.default = 5672 ``` 这样rabbitmq就会监听5672端口。 3. 启动rabbitmq-server ``` sudo service rabbitmq-server start ``` 4. 创建用户并设置权限 ``` sudo rabbitmqctl add_user username password sudo rabbitmqctl set_user_tags username administrator sudo rabbitmqctl set_permissions -p / username ".*" ".*" ".*" ``` 这里创建了一个用户名为username,密码为password的用户,并给其设置了administrator角色和所有权限。 5. 在另一台器上安装rabbitmq-client 同样需要运行以下命令: ``` sudo apt-get update sudo apt-get install rabbitmq-client ``` 6. 在本上创建一个队列并发送消息 使用命令行工具rabbitmqadmin创建一个名为test_queue的队列,并向其发送一条消息: ``` sudo rabbitmqadmin declare queue name=test_queue sudo rabbitmqadmin publish exchange=amq.default routing_key=test_queue payload="Hello World" ``` 7. 在另一台器上接收消息 使用以下命令接收在test_queue队列中的消息: ``` sudo rabbitmqadmin get queue=test_queue ``` 如果一切顺利,你将会看到输出中包含"Hello World"消息。 注意事项: - 在rabbitmq管理员手册中了解更多关于配置rabbitmq-server和访问控制的细节 - 如果在使用rabbitmqadmin时出现权限错误,可以使用一个带有管理员权限的用户来运行rabbitmqadmin - 在生产环境中,应该使用SSL或者其他安全协议来保护跨器通信的安全性

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

利威尔·

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值