网络编程之UDP简单示例

UDP编程函数recvfrom()、inet_pton()、sendto()

  1. UDP协议 user data protrol 用户数据协议特点:
    TCP: 面向连接 --> 一定双方连接上了才能进行通信!
    UDP: 面向非连接 --> 不需要连接就可以进行数据的收发,提高效率。

UDP例子: 写信

  1. UDP实现过程

例题: 客户端发送数据给服务器,使用UDP完成。

服务器:(收信) Rose.c

(1). 买一个信箱

int fd = socket(AF_INET,SOCK_DGRAM,0);

(2). 绑定一个地址到信箱

struct sockaddr_in srvaddr;
srvaddr.sin_family = AF_INET; //协议
srvaddr.sin_port = htons(atoi(argv[1])); //端口号
srvaddr.sin_addr.s_addr = htonl(INADDR_ANY); //IP地址

bind(fd,(struct sockaddr *)&srvaddr,len);

(3). 不断收信

recvfrom(fd,buf,sizeof(buf),0,(struct sockaddr *)&cliaddr,&len);	

(4). 销毁信箱

close(fd);

客户端:(写信)

(1). 买一个信箱

int fd = socket(AF_INET,SOCK_DGRAM,0);

(2). 准备服务器地址

struct sockaddr_in srvaddr;
socklen_t len = sizeof(srvaddr);
srvaddr.sin_family = AF_INET;
srvaddr.sin_port = htons(atoi(argv[2]));
inet_pton(AF_INET,argv[1],&srvaddr.sin_addr);

(3). 不断往服务器地址写信

sendto(fd,buf,strlen(buf),0,(struct sockaddr *)&srvaddr,len);

(4). 销毁信箱

close(fd);

例子:

Jack.c

备注:本次测试为Linux Ubuntu18.04系统,更新原文章头文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <arpa/inet.h>

int main(int argc,char *argv[])  //  ./Jack 192.168.0.243 50002
{
    
    
	//1. 创建UDP套接字(没有地址的信箱)
	int fd = socket(AF_INET,SOCK_DGRAM,0);
	
	//2. 准备服务器的地址
	struct sockaddr_in srvaddr;
	socklen_t len = sizeof(srvaddr);
	srvaddr.sin_family = AF_INET;
	srvaddr.sin_port = htons(atoi(argv[2]));
	inet_pton(AF_INET,argv[1],&srvaddr.sin_addr);
	
	//AF_INET: 协议,与socket第一个参数一致
	//argv[1]: 代表一个字符串,"192.168.0.243"
	//&srvaddr.sin_addr: 代表struct in_addr *类型,使用srvaddr变量访问sin_addr这个变量,再取地址就变成指针了!
	/*
struct sockaddr_in
{           
       u_short sin_family;	// 地址族
       u_short sin_port;	// 端口
       struct in_addr sin_addr;	// IPV4地址
       char sin_zero[8];
};
*/
	
	//3. 不断写信
	char buf[50];
	while(1)
	{
    
    
		bzero(buf,50);
		fgets(buf,50,stdin);
		sendto(fd,buf,strlen(buf),0,(struct sockaddr *)&srvaddr,len);
		if(strncmp(buf,"quit",4) == 0)
			break;
	}
	
	//4. 回收套接字资源
	close(fd);
	
	return 0;
}

Rose.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>

int main(int argc,char *argv[])  //  ./Rose 50001
{
    
    
	//1. 创建UDP套接字(没有地址的信箱)
	int fd = socket(AF_INET,SOCK_DGRAM,0);
	
	//2. 准备服务器的IP地址(准备地址)
	struct sockaddr_in srvaddr;
	socklen_t len = sizeof(srvaddr);	
	bzero(&srvaddr,len);
	
	srvaddr.sin_family = AF_INET; //协议
	srvaddr.sin_port = htons(atoi(argv[1])); //端口号
	srvaddr.sin_addr.s_addr = htonl(INADDR_ANY); //IP地址
	
	//3. 绑定地址到套接字(把准备好的地址绑定到信箱上)
	bind(fd,(struct sockaddr *)&srvaddr,len);
	
	//4. 不断从UDP套接字中接收数据
	struct sockaddr_in cliaddr;
	char buf[50];
	while(1)
	{
    
    
		bzero(buf,50);
		//不断从fd这个信箱上读取cliaddr这个客户端给我发来的内容,然后存放在buf中
		recvfrom(fd,buf,sizeof(buf),0,(struct sockaddr *)&cliaddr,&len);	
		printf("from Jack:%s",buf);
		
		if(strncmp(buf,"quit",4) == 0)
			break;
	}
	
	//5. 关闭套接字资源
	close(fd);
	
	return 0;
}

运行步骤:

同桌Ubuntu      你的Ubuntu
Rose.c              Jack.c
192.168.0.10    192.168.0.20
50001                50001

同桌: ping 192.168.0.20
你:   ping 192.168.0.10

同桌: ./Rose 50001
你:   ./Jack 192.168.0.10 50001

猜你喜欢

转载自blog.csdn.net/sinat_36002055/article/details/120563637