0
点赞
收藏
分享

微信扫一扫

树莓派与Matlab 进行TCP\IP 通信并传输文件

凶猛的小白兔 2022-03-14 阅读 133

文章大纲

TCP\IP 协议

TCP\IP协议的建立,通过服务器与客户端的三次握手建立。客户端首先向服务器端口发送SYN连接请求后,等待接收从服务器端口传来的SYN和ACK报文,客户端接收到后回应服务器ACK报文,此时服务器和客户端连接成功。
在这里插入图片描述

服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。
在这里插入图片描述
本次实验采用的是Matlab作为服务器端,树莓派(Linux系统)作为客户端。流程图大致如下:

在这里插入图片描述

Matlab 作为服务器端,调用服务器端接口代码如下:

%与第一个请求连接的客户机建立连接,端口号为6668,类型为服务器。
t_server=tcpip('192.168.1.100',6666,'NetworkRole','server');
t_server.InputBuffersize=1024;%缓冲区放大到1024
t_server.Timeout=20;% 设置超时时间
fclose(t_server);
set(t_server,'RemoteHost','192.168.1.105');
fopen(t_server);%打开服务器,直到建立一个TCP连接才返回;
fprintf("Accept connect from %s \n",t_server.RemoteHost);

其中要注意的一点是,要设定与服务器相连接的客户端的IP地址,才能够进行通信,否则Matlab端并不会和客户端建立联系,从而一直堵塞在等待连接状态,一直到超时,才能退出。

树莓派作为客户端,用C语言编写,代码如下:

//  socket 包括 协议,地址,端口
  server_addr.sin_family =AF_INET;// IPV4 协议
  server_addr.sin_addr.s_addr = inet_addr(server_ip);
  server_addr.sin_port =htons(server_port);
  int sfd;
  // socket   套接字函数
  // socket(int domain ,int type ,int protocal)
  // domain 地址类型 ,AF_INET 为 IPV4 类型
  // type 数据流,SOCK_STREAM为 TCP数据流
  // protocal 一般设置为0 
  // 失败返回-1 ,成功返回socket 代码
  sfd = socket(AF_INET,SOCK_STREAM,0);
  if(sfd<0)
  {
    printf("socket error: %s(errno : %d)\n",strerror(errno),errno);
    exit(0);
  
  }

  // 常用于客户端建立TCP链接
  // 第一个参数为 套接字,
  // 第二个参数为 连接的主机地址和端口
  // 缓冲区长度
  if(connect(sfd,(struct sockaddr*)&server_addr,sizeof(server_addr)) < 0 )
  {
    printf("Can not connect to %s\n",argv[1]);
    exit(1);
  }
  printf("连接成功\n\n");

Matlab 发送给客户端采用fprintf(t_server,'%s','Content')其中,第一个参数为服务器的套接字,第二个参数为发送的类型,第三个参数为发送的内容。
Matlab 从客户端接收采用fread(t_server,Size)其中,第一个参数为服务器的套接字,第二个参数为接收的大小。注意!!当服务器没有从客户端接收到这么大的字节时,会一直堵塞,直到超时。

树莓派发送给服务器采用send(sfd,buffer,length,0)其中第一个参数为套接字,第二个参数为发送的字符串数组,第三个参数为字符串的长度,第四个参数默认为0。

树莓派从服务器接收采用recv(sdf,buffer,length,0),参数同发送。
注意!由于Matlab的接收的特殊性,一定要确定好Size大小。因此,一般树莓派先发送文件的大小,让Matlab端知道要定义多大的存储空间,然后在发送内容。

文件流的传输

就如刚才所说的,一定要确定好文件的大小。采用下面的代码获取文件的大小。

 if((stream=fopen(Filename,"r"))==NULL)
    {
      printf("open failed \n" );
      exit(1);
    }
    long size = 0;
    char tmp;
    while(fread(&tmp,1,1,stream))
    {
         size++;
    }

注意!!文件流使用过一遍,就会是失效(我也不知道为啥),要重新再赋值一遍才可以,即在此执行一遍fopen,然后再传输文件,代码如下

		stream=fopen(Filename,"r");
		while((len=fread(buffer,1,1024,stream))>0)
		{
			printf("正在传输\n");
			if(send(sfd,buffer,len,0)<0)
			{	
				printf("send failed\n");
				break;
			}
			bzero(buffer,BUFFER_SIZE);
		}
		printf("传输完毕\n\n");
举报

相关推荐

0 条评论