编译运行UDP client/sever,然后利用send()和recv()分别代替sendto()和recvfrom()

1.题目1

编译运行UDP client/sever(https://www.geeksforgeeks.org/udp-server-client-implementation-c/),最好在不同的机器上运行,也可以在Linux上安装Linux虚拟机,或者买树莓派,并用wireshark抓包。
运行环境是在windows下的Ubuntu虚拟机和树莓派虚拟机。在一开始指定服务器的IP地址之后客户端接受的数据后面会出现乱码,而服务端则没有出现。对比两个之间的代码后发现客户端这边接受数据的代码部分中的函数recvfrom函数的最后一个参数的接收长度没有提前求出来,导致输出的时候把未用完的缓存的数组的空间也读取出来,所以就出现了乱码,修改之后就没有问题了。
在这里插入图片描述

可以看到,由于UDP是无连接的,客户端和服务端也只有两次通信来往,所以抓的包也是只有两次,其中服务端的IP地址是192.168.61.128,客户端的IP地址是192.168.61.129。

2.题目2

上面的程序利用send()和recv()分别代替sendto()和recvfrom()。提示:调用connect()函数,man一下,再搜索如何替代。代替前后的client端IP和port是谁创建的?是多少?
在这里插入图片描述
在这里插入图片描述

与之前的代码的区别主要是在调用send和recv之前利用connect函数连接两个主机便可以代替sendto和recvfrom。可知客户端的IP和port是由socket创建的,分别是192.168.31.128和38576。

3.源码

3.1服务端

// Server side implementation of UDP client-server model 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <arpa/inet.h> 
#include <netinet/in.h> 
  
#define PORT     8080 
#define MAXLINE 1024 
  
// Driver code 
int main()
{ 
    int sockfd; 
    char buffer[MAXLINE]; 
    char *hello = "Hello from server"; 
    struct sockaddr_in servaddr, cliaddr; 
      
    // Creating socket file descriptor 
    if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 )
    { 
        perror("socket creation failed"); 
        exit(EXIT_FAILURE); 
    } 
      
    memset(&servaddr, 0, sizeof(servaddr)); 
    memset(&cliaddr, 0, sizeof(cliaddr)); 

    // Filling server information 
    servaddr.sin_family    = AF_INET; // IPv4 
    servaddr.sin_addr.s_addr = INADDR_ANY; 
    servaddr.sin_port = htons(PORT); 
   
    // Bind the socket with the server address 
    if ( bind(sockfd, (const struct sockaddr *)&servaddr, 
                     sizeof(servaddr)) < 0 )
    { 
        perror("bind failed"); 
        exit(EXIT_FAILURE); 
    } 
   
   //Filling client information
    int len, n;
    len = sizeof(cliaddr);  //len is value/resuslt

    n = recvfrom(sockfd, (char *)buffer, MAXLINE, MSG_WAITALL, (struct sockaddr *)&cliaddr, &len); 
    buffer[n] = '\0';
    printf("Client : %s\n", buffer);
    sendto(sockfd, (const char *)hello, strlen(hello), MSG_CONFIRM, (struct sockaddr *)&cliaddr, len); 
    printf("Hello message sent.\n");  
      
    return 0; 
}

3.2客户端

// Client side implementation of UDP client-server model 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <arpa/inet.h> 
#include <netinet/in.h> 

#define PORT    8080 
#define MAXLINE 1024

// Driver code 
int main()
{ 
	int sockfd; 
	char buffer[MAXLINE]; 
	char *hello = "Hello from client"; 
	struct sockaddr_in servaddr, cliaddr; 

	// Creating socket file descriptor 
	if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 )
	{ 
		perror("socket creation failed"); 
		exit(EXIT_FAILURE); 
	} 

	memset(&servaddr, 0, sizeof(servaddr)); 
	
	// Filling server information 
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(PORT); 
	servaddr.sin_addr.s_addr = inet_addr("192.168.61.131");
    if (connect(sockfd, (struct sockaddr* )&servaddr, 
                         sizeof(struct sockaddr_in)) < 0)
    {
		perror("socket");
		exit(EXIT_FAILURE);
	}

    int n, len;
	send(sockfd, (const char *)hello, strlen(hello), MSG_CONFIRM); 
	printf("Hello message sent.\n"); 
	n = recv(sockfd, (char *)buffer, MAXLINE, MSG_WAITALL);
    buffer[n] = '\0'; 
	printf("Server : %s\n", buffer); 

	close(sockfd); 
	return 0; 
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值