虛擬機ubuntu和開發板UDP Socket通信實例

服務器端的步驟如下:

1. socket:      建立一個socket

2. bind:          將這個socket綁定在某個端口上(AF_INET)

3. recvfrom:  如果沒有客戶端發起請求,則會阻塞在這個函數裏

4. close:        通信完成後關閉socket

客戶端的步驟如下:

1. socket:      建立一個socket

2. sendto:     向服務器的某個端口發起請求(AF_INET)

3. close:        通信完成後關閉socket

 

基於UDP的接收和發送函數

int recvfrom(int sockfd, void * buf, size_t len, int flags, struct sockaddr * src_addr, socklen_t * addrlen);

int sendto(int sockfd, const void * buf, size_t len, int flags, const struct sockaddr * dest_addr, socklen_t addrlen);

UDP套接字不會保持連接狀態,每次傳輸數據都要添加目標地址信息,這相當於在郵寄包裹前填寫收件人地址。

 

recvfrom用於接收數據,sendto用於發送數據

recvfrom:

  • sockfd:用於接收UDP數據的套接字;
  • buf:保存接收數據的緩衝區地址;
  • len:可接收的最大字節數(不能超過buf緩衝區的大小);
  • flags:可選項參數,若沒有可傳遞0;
  • src_addr:存有發送端地址信息的sockaddr結構體變量的地址;
  • addrlen:保存參數 src_addr的結構體變量長度的變量地址值。

sendto:

  • sockfd:用於傳輸UDP數據的套接字;
  • buf:保存待傳輸數據的緩衝區地址;
  • len:帶傳輸數據的長度(以字節計);
  • flags:可選項參數,若沒有可傳遞0;
  • dest_addr:存有目標地址信息的 sockaddr 結構體變量的地址;
  • addrlen:傳遞給參數 dest_addr的地址值結構體變量的長度。

Client.cpp

#include <stdio.h>   
#include <string.h>   
#include <errno.h>   
#include <stdlib.h>   
#include <unistd.h>   
#include <sys/types.h>   
#include <sys/socket.h>   
#include <netinet/in.h>   
#include <arpa/inet.h>   
   
  
#define DEST_PORT 8000
#define DSET_IP_ADDRESS  "192.168.1.123"
  
int main()  
{  
  /* socket文件描述符 */  
  int sock_fd;  
  
  /* 建立udp socket */  
  sock_fd = socket(AF_INET, SOCK_DGRAM, 0);  
  if(sock_fd < 0)  
  {  
    perror("socket");  
    exit(1);  
  }  
    
  /* 設置address */  
  struct sockaddr_in addr_serv;  
  int len;  
  memset(&addr_serv, 0, sizeof(addr_serv));  
  addr_serv.sin_family = AF_INET;  
  addr_serv.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);  
  addr_serv.sin_port = htons(DEST_PORT);  
  len = sizeof(addr_serv);  
  
    
  int send_num;  
  int recv_num;  
  char send_buf[20] = "hey, who are you?";  
  char recv_buf[20];  
  
	while(1)
	{
	  printf("client send: %s\n", send_buf);  
	  
	  send_num = sendto(sock_fd, send_buf, strlen(send_buf), 0, (struct sockaddr *)&addr_serv, len);  
		
	  if(send_num < 0)  
	  {  
		perror("sendto error:");  
		exit(1);  
	  }  
		
	  recv_num = recvfrom(sock_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&addr_serv, (socklen_t *)&len);  
		
	  if(recv_num < 0)  
	  {  
		perror("recvfrom error:");  
		exit(1);  
	  }  
		
	  recv_buf[recv_num] = '\0';  
	  printf("client receive %d bytes: %s\n", recv_num, recv_buf);  

		sleep(10);
	}

    
  close(sock_fd);  
    
  return 0;  
}

Server.cpp

#include <stdio.h>   
#include <sys/types.h>   
#include <sys/socket.h>   
#include <netinet/in.h>   
#include <unistd.h>   
#include <errno.h>   
#include <string.h>   
#include <stdlib.h>   
  
#define SERV_PORT   8000

int main()  
{  
  /* sock_fd --- socket文件描述符 創建udp套接字*/  
  int sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
  if(sock_fd < 0)  
  {  
    perror("socket");  
    exit(1);  
  }  
  
  /* 將套接字和IP、端口綁定 */  
  struct sockaddr_in addr_serv;  
  int len;  
  memset(&addr_serv, 0, sizeof(struct sockaddr_in));  //每個字節都用0填充
  addr_serv.sin_family = AF_INET;//使用IPV4地址
  addr_serv.sin_port = htons(SERV_PORT);//端口
  /* INADDR_ANY表示不管是哪個網卡接收到數據,只要目的端口是SERV_PORT,就會被該應用程序接收到 */  
  addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);  //自動獲取IP地址
  len = sizeof(addr_serv);  
    
  /* 綁定socket */  
  if(bind(sock_fd, (struct sockaddr *)&addr_serv, sizeof(addr_serv)) < 0)  
  {  
    perror("bind error:");  
    exit(1);  
  }  
  
    
  int recv_num;  
  int send_num;  
  char send_buf[20] = "i am server!";  
  char recv_buf[20];  
  struct sockaddr_in addr_client;  
  
  while(1)  
  {  
    printf("server wait:\n");  
      
    recv_num = recvfrom(sock_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&addr_client, (socklen_t *)&len);  
      
    if(recv_num < 0)  
    {  
      perror("recvfrom error:");  
      exit(1);  
    }  
  
    recv_buf[recv_num] = '\0';  
    printf("server receive %d bytes: %s\n", recv_num, recv_buf);  
  
    send_num = sendto(sock_fd, send_buf, recv_num, 0, (struct sockaddr *)&addr_client, len);  
      
    if(send_num < 0)  
    {  
      perror("sendto error:");  
      exit(1);  
    }  
  }  
    
  close(sock_fd);  
    
  return 0;  
}

 虛擬機作爲client,開發板作爲server。

運行前,確保虛擬機和開發板可以互相ping通

 

參考文獻:https://www.cnblogs.com/zkfopen/p/9382705.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章