UDP basic application and broadcast case

table of Contents

UDP client server model

data transmission

send data

Accept data

Server program code

Client program code

broadcast

Broadcast receiver

Sender of the broadcast

UDP client server model

data transmission

send data

#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t nbytes, int flag);
  • Return: Return the number of bytes sent if successful, and -1 if error occurs.
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flag);
  • Return: Return the number of bytes sent if successful, and -1 if error occurs.
ssize_t sendto(int sockfd, const void *buf, size_t nbytes, int flag,
                const struct sockaddr *destaddr, socklen_t destlen);
  • Return: Return the number of bytes sent if successful, and -1 if error occurs.
struct msghdr{
    void *msg_name; /*optional address*/
    socklen_t msg_namelen; /*address size in bytes*/
    struct iovec *msg_iov; /*array of I/O buffers*/
    int msg_iovlen; /*number of elements in array */
    void *msg_control; /*ancillary data*/
    socklen_t msg_controllen; /*number of ancillary bytes*/
    int msg_flags; /*flags for received message*/
}

Accept data

#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t nbytes, int flag);
ssize_t recvfrom(int sockfd, void *restrict buf, size_t len, int flag,
                struct sockaddr *restrict addr, socklen_t *restrict addrlen);
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flag);
  • Return: Return the number of bytes of the message, 0 if no message, -1 if error

Server program code

int sockfd; 
void sig_handler(int signo)
{
	if(signo==SIGINT)
	{
		printf("server close\n"); 
		close(sockfd); 
		exit(1);
	}
}

//输出客户端的信息
void out_addr(struct sockaddr_in* clientaddr)
{
	char ip[16];
	memset(ip,0,sizeof(ip));
	inet_ntop(AF_INET, &clientaddr->sin_addr.s_addr,ip, sizeof(ip));
	int port=ntohs(clientaddr->sin_port);
	printf("client:%s(%d)\n", ip, port);
}

//和客户端进行通信
void do_service(int fd)
{
	struct sockaddr_in clientaddr;
	socklen_t len = sizeof(clientaddr);
	
	char buffer[1024];
	memset(buffer, 0, sizeof(buffer));
	
	//接受客户端的数据报文
	if(recvfrom(sockfd,buffer, sizeof(buffer), 0,
				(struct sockaddr*)&clientaddr, &len)<0)
	{
		perror("recvfrom error");
	}
	else
    {		
		out_addr(&clientaddr);
		printf("client send info:%s\n", buffer);
		
		//向客户端发送数据报文
		long int t =time(0);
		char*ptr = ctime(&t);
		
		size_t size = strlen(ptr)*sizeof(char);
		if(sendto(sockfd, ptr, size, 0, \
			(struct sockaddr*)&clientaddr, len)<0)
		{
			perror("sendto error"); 			
		}
	}
}

int main(int argc, char *argv[])
{
	if(argc<2)
	{
		printf("usage:%s port\n",argv[0]); 
		exit(1); 
	}
	
	if(signal(SIGINT, sig_ handler) == SIG_ERR)
	{
		perror("signal sigint error"); 
		exit(1);
	}
	
	/*步骤1:创建 socket*/
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if(sockfd < 0)
	{
		perror("socket error");
		exit(1);
	}

	int ret;
	int opt=1;
	//设置套接字选项
	if((ret=setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, \
						sizeof(opt)))<0)
	{
		perror("setsockopt error");
		exit(1);
	}
	
	/*步骤2:调用bind函数对socket和地址进行绑定*/
	struct sockaddr_in serveraddr;
	memset(&serveraddr, 0, sizeof(serveraddr));
	serveraddr.sin_family = AF_INET;//IPV4
	serveraddr.sin_port = htons(atoi(argv[1]));//port 
	serveraddr.sin_addr.s_addr = INADDR_ANY;//ip 
	
	if(bind(sockfd, (struct sockaddr*)&serveraddr, \
					sizeof(serveraddr))<0)
	{
		perror("bind error");
		exit(1);
	}

	/*步骤3:和客户端进行双向的数据通信*/
	while(1){
		do_service();
		return 0;
	}	
}

Client program code

int main(int argc,char *argv[])
{
	if(argc < 3)
	{
		printf("usage:%s ip port\n", argv[0]); 
		exit(1);
	}

	/*步骤1:创建 socket*/
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if(sockfd < 0)
	{
		perror("socket error");
		exit(1);
	}

	/*步骤2:调用recvfrom和sendto等函数
	*和服务器端双向通信
	*/
	struct sockaddr_in serveraddr;
	memset(&serveraddr, 0, sizeof(serveraddr));
	serveraddr.sin_family = AF_INET;//IPV4
	serveraddr.sin_port = htons(atoi(argv[1]));//port 
	serveraddr.sin_addr.s_addr = INADDR_ANY;//ip 

	if(connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0)
	{
		perror("connect error"); 
		exit(1);
	}

	char buffer[1024] = "Hello world!";
	//向服务器端发送数据报文
	//if(sendto(sockfd, buffer, sizeof(buffer), 0,\
	//		(struct sockaddr*)&serveraddr,sizeof(serveraddr)) < 0)
	if(sendto(sockfd, buffer, sizeof(buffer), 0) < 0)
	{
		perror("sendto error");
		exit(1);
	}
	else
	{
		//接受服务器端发送的数据报文
		memset(buffer, 0, sizeof(buffer));
		size_t size;
		
		if(recv(sockfd, buffer, sizeof(buffer), 0) <0 )
		{
			perror("recv error");
			exit(1);
		}
		else
		{
			printf("%s",buffer); 			
		}
	}
	close(sockfd);
	
	return 0;
}

broadcast

  • The SO_BROADCAST option controls whether a UDP socket can send broadcast datagrams. The type of the option is int, and non-zero means "yes". Note that only UDP sockets can use this option, and TCP cannot use broadcast.
int opt = 1;
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
//错误处理
}
if(setsockopt(sockfd, SOL_SOCKET,
    SO_BROADCAST, &opt, sizeof(opt)) < 0)
{
//错误处理
}

Broadcast receiver

int sockfd; 
void sig_handler(int signo)
{
	if(signo==SIGINT)
	{
		printf("server close\n"); 
		close(sockfd); 
		exit(1);
	}
}

int main(int argc, char *argv[])
{
	if(argc<2)
	{
		printf("usage:%s port\n",argv[0]); 
		exit(1); 
	}
	
	if(signal(SIGINT, sig_handler) == SIG_ERR)
	{
		perror("signal sigint error"); 
		exit(1);
	}
	
	/*步骤1:创建 socket*/
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if(sockfd < 0)
	{
		perror("socket error");
		exit(1);
	}

	/*步骤2:调用bind函数对socket和地址进行绑定*/
	struct sockaddr_in serveraddr;
	memset(&serveraddr, 0, sizeof(serveraddr));
	serveraddr.sin_family = AF_INET;//IPV4
	serveraddr.sin_port = htons(atoi(argv[1]));//port 
	serveraddr.sin_addr.s_addr = INADDR_ANY;//ip 
	
	if(bind(sockfd, (struct sockaddr*)&serveraddr, \
					sizeof(serveraddr))<0)
	{
		perror("bind error");
		exit(1);
	}

	char buffer[1024]; 
	struct sockaddr_in clientaddr; 
	socklen_t len=sizeof(clientaddr); 
	
	while(1){
		memset(buffer, 0, sizeof(buffer)); 
		memset(&clientaddr, 0, sizeof(clientaddr)); 
		if(recvfrom(sockfd, buffer, sizeof(buffer),0,\
				(struct sockaddr*)&clientaddr, &len)<0)
		{
			perror("recvfrom error"); 
			exit(1);
		} 
		else
		{
			char ip[16]; 
			inet_ntop(AF_INET, &clentaddr.sin_addr.s_addr, ip, sizeof(ip)); 
			int port=ntohs(clientaddr.sin_port); 
			printf("%s(%d):%s\n", ip, port, buffer);
		}
	}	
	close(sockfd);	
	return 0;	
}

Sender of the broadcast

int sockfd; 

int main(int argc, char *argv[])
{
	if(argc<2)
	{
		printf("usage:%s port\n", argv[0]); 
		exit(1); 
	}
	
	/*步骤1:创建 socket*/
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if(sockfd < 0)
	{
		perror("socket error");
		exit(1);
	}

	int opt=1;//采用广播方式发送
	setsockopt(sockfd, SOL_SOCKET,SO_BROADCAST, &opt, sizeof(opt));
	
	struct sockaddr_in serveraddr;
	memset(&serveraddr, 0, sizeof(serveraddr));
	serveraddr.sin family=AF_INET;
	serveraddr.sin_port = htons(atoi(argv[2]));
	inet_pton(AF_INET, argv[1], &serveraddr.sin_addr.s_addr);
	
	printf("I will broadcast...\n"); 
	char * info="hello iotek"; 
	size_t size=strlen(info)* sizeof(char);
	
	if(sendto(sockfd, info, size,0,
			(struct sockaddr*)&serveraddr, sizeof(serveraddr))<0)
	{ 
		perror("sendto error"); 
		exit(1);
	} 
	else
	{
		printf("boradcast success\n");
	}
	
	close(sockfd);
	
	return 0;	
}

 

Guess you like

Origin blog.csdn.net/baidu_41388533/article/details/111707198