网络编程练习-UDP套接字

UDP是不保证数据传输的完整性,不基于连接,所以没有TCP的connect函数

TCP的发送和接收使用recvfrom和sendto函数,对端信息可以从这两个函数的最后两个函数的最后两个参数来获取或者设置。

1,基本的UDP c/s通信demo:

<span style="font-size:14px;">/*************************************************************
 * file: udp_socket.c
 * brief:udp demo program
 * yejing@2015.3.25    1.0      creat
 *************************************************************/
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <errno.h>
 #include <string.h>
 #include <netinet/in.h>
 
 #define PORT  9527
 
 #if defined(SERVER)
 int main(int argc, char* argv[]){
	int sockfd;
	struct sockaddr_in sockaddr_cli;
	struct sockaddr_in sockaddr_svr;
	
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if(!sockfd){
		fprintf(stderr, "socket create error. \n");
		return -1;
	}
	
	sockaddr_svr.sin_family = AF_INET;
	sockaddr_svr.sin_port   = htons(PORT);
	inet_pton(AF_INET, "127.0.0.1", &sockaddr_svr.sin_addr);
	
	int ret = bind(sockfd, (const struct sockaddr*)&sockaddr_svr, sizeof(sockaddr_svr));
	if(ret < 0){
		fprintf(stderr, "socket bind error. errno:%d \n", errno);
		return -1;
	}
	
	while(1){
		char buf[10];
		memset(buf, 0, sizeof(buf));
		socklen_t sock_cli_len;
		printf("read to recv \n");
		ret = recvfrom(sockfd, buf, 10, 0, (struct sockaddr*)&sockaddr_cli, &sock_cli_len);
		printf("ret = %d \n", ret);
		#if 1
		printf("rcving data:");
		int i = 0;
		for(i = 0; i < ret; ++i)
			printf("%c ", buf[i]);
		printf("\n");
		#endif
		if(ret){
			ret = sendto(sockfd, buf, 10, 0, (const struct sockaddr*)&sockaddr_cli, sock_cli_len);
			printf("ret = %d errno:%d \n", ret, errno);
		}
	}
 }
 #else
 
 int main(int argc, char* argv[]){
	int sockfd;
	struct sockaddr_in sock_svr;
	
	memset((char*)&sock_svr, 0, sizeof(sock_svr));
	
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if(!sockfd){
		fprintf(stderr, "socket create error, errno:%d \n", errno);
		return -1;
	}
	
	sock_svr.sin_family = AF_INET;
	sock_svr.sin_port   = htons(PORT);
	//inet_pton(AF_INET, argv[1], &sock_svr.sin_addr);
	inet_pton(AF_INET, "127.0.0.1", &sock_svr.sin_addr);
	
	while(1){
		char sendbuf[10] = "asdfghjkl";
		char rcvbuf[10] = {0};
		int ret = sendto(sockfd, sendbuf, 10, 0, (const struct sockaddr*)&sock_svr, sizeof(sock_svr));
		if(ret){
			printf("sending data ... \n");
			sleep(1);
			printf("ret = %d 111\n", ret);
			ret = recvfrom(sockfd, rcvbuf, 10, 0, NULL, NULL);
			printf("ret = %d \n", ret);
			if(ret){
				printf("rcving echo:");
				int i = 0;
				for(i = 0; i < ret; ++i)
					printf("%c ", rcvbuf[i]);
				printf("\n");
			}
		}
	}
 }
 #endif</span>


可靠性UDP编程:

如果想要让请求-应答式应用程序使用UDP,那么必须在客户程序中增加以下两个特性:

1,超时和重传,用于处理丢失的数据包

2,序列号,供客户验证一个应答是否匹配相应的请求。



并发UDP服务器:

与基于连接的TCP服务只是新创建一个task处理一个新的请求连接不同,UDP需要处理一下两种不同类型的服务器:

1,读入一个请求,发送一个应答,就不再跟这个客户交互

    这种情形,读入客户请求的服务器可以通过创建一个task处理该请求。

2,服务器需要与客户多次交换数据

    这个问题的关键在于服务器如何区分来至客户端的数据报属于哪个client,即归类client发来的数据包。方法通常是服务器为每个client创建一个新的socket,在上面绑定一个临时端口号,使用此端口号发送对client的应答,同时client需要记录server第一个应答的端口号,client的后续请求数据通过这个port发送给server。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值