UDP 套接字 recvfrom & sendto

时光总嘲笑我的痴心妄想 提交于 2019-12-17 03:06:46

UDP编程中,服务器不接受来自客户端的连接,只管调用recvfrom函数,阻塞等待客户端的连接。

UDP都是以数据报的形式进行发送和接收的,而TCP是以数据流的形式进行发送和接收的。

客户服务流程结构如下:

 

recvfrom和sendto函数

函数定义:

int sendto (int s, const void *buf, int len, unsigned int flags, const struct sockaddr *to, int tolen);

int recvfrom(int s, void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen);

函数说明:

sendto(),是把UDP数据报发给指定地址;

recvfrom()是从指定地址接收UDP数据报。

 

参数:

  • s:             socket描述符。
  • buf:          UDP数据报 发送/接收 缓存地址。
  • len:          UDP数据报长度。
  • flags:       该参数一般为0。
  • to:            sendto()函数参数,struct sockaddr_in类型,指明UDP数据发往哪里报,手动填充对端数据。
  • tolen:       对方地址长度,一般为:sizeof(struct sockaddr_in)。
  • from:        recvfrom()函数参数,struct sockaddr_in类型,指明从哪里接收UDP数据报,函数自动填充对端数据。

 

函数举例:


server:

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

#define	UDP_TEST_PORT		50001

int main(int argC, char* arg[])
{
	struct sockaddr_in addr;
	int sockfd, len = 0;	
	int addr_len = sizeof(struct sockaddr_in);
	char buffer[256];	

	/* 建立socket,注意必须是SOCK_DGRAM */
	if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		perror ("socket");
		exit(1);
	}

	/* 填写sockaddr_in 结构 */
	bzero(&addr, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(UDP_TEST_PORT);
	addr.sin_addr.s_addr = htonl(INADDR_ANY) ;// 接收任意IP发来的数据

	/* 绑定socket */
	if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr))<0) {
		perror("connect");
		exit(1);
	}

	while(1) {
		bzero(buffer, sizeof(buffer));
        //接收到数据之前,在recvfrom中阻塞等待,接收数据存放在buffer中
		len = recvfrom(sockfd, buffer, sizeof(buffer), 0, 
					   (struct sockaddr *)&addr ,&addr_len);
		/* 显示client端的网络地址和收到的字符串消息,从addr 中获取:*/
		printf("Received a string from client %s, string is: %s\n", 
				inet_ntoa(addr.sin_addr), buffer);
		/* 将收到的字符串消息返回给client端,buffer中存放发送数据:*/
		sendto(sockfd, buffer, len, 0, (struct sockaddr *)&addr, addr_len);
	}

	return 0;
}

client:

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

#define	UDP_TEST_PORT		50001
#define UDP_SERVER_IP 		"127.0.0.1"

int main(int argC, char* arg[])
{
	struct sockaddr_in addr;
	int sockfd, len = 0;	
	int addr_len = sizeof(struct sockaddr_in);		
	char buffer[256];

	/* 建立socket,注意必须是SOCK_DGRAM */
	if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		perror("socket");
		exit(1);
	}

	/* 填写需要发送到的server的信息到sockaddr_in addr 中:*/
	bzero(&addr, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(UDP_TEST_PORT);
	addr.sin_addr.s_addr = inet_addr(UDP_SERVER_IP);

	while(1) {
		bzero(buffer, sizeof(buffer));

		printf("Please enter a string to send to server: \n");

		/* 从标准输入设备取得字符串*/
		len = read(STDIN_FILENO, buffer, sizeof(buffer));

		/* 将字符串传送给server端,发送时候存放在buffer中*/
		sendto(sockfd, buffer, len, 0, (struct sockaddr *)&addr, addr_len);

		/* 接收server端返回的字符串,server信息自动填充到addr中,获取数据在buffer中*/
		len = recvfrom(sockfd, buffer, sizeof(buffer), 0, 
				       (struct sockaddr *)&addr, &addr_len);
		printf("Receive from server: %s\n", buffer);
	}

	return 0;
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!