网络编程:C/S模型 - UDP

目录

一、UDP模型

1、服务端

2、客户端

二、测试程序

1、服务端

2、客户端


一、UDP模型

1、服务端

        没有 accept,不需要建立建立连接;

        使用 recvfrom 代替 read,失败返回 -1,成功返回 - 从内核缓冲区读到的字节数

        使用 sendto 代替 write,失败返回 -1,成功返回 - 写到内核缓冲区的字节数

struct sockaddr_in servaddr;
struct sockaddr_in connaddr;  
socklen_t servsocklen;          // 本地已知
socklen_t connsocklen;          // 对端未知


lfd = socket(AF_INET, SOCK_DGRAM, 0);

bind(lfd, &servaddr, servsocklen);       //(struct sockaddr *)&servaddr

listen(lfd, maxlistensize);


while(1) {

    // lfd 接收 data 从 connaddr, 传出 connaddr
    len = recvfrom(lfd, buf, sizeof(buf), 0, &connaddr, &connsocklen);  //(struct sockaddr *)&connaddr

    // lfd 发送 data 到 connaddr, 传入 connaddr
    len = sendto(lfd, buf, len, 0, &connaddr, connsocklen);
}

2、客户端

        没有 connect,不需要建立建立连接;

        使用 sendto 代替 write,失败返回 -1,成功返回 - 写到内核缓冲区的字节数

        使用 recvfrom 代替 read,失败返回 -1,成功返回 - 从内核缓冲区读到的字节数

struct sockaddr_in servaddr;
struct sockaddr_in clieaddr;  
socklen_t servsocklen;          // 对端已知
socklen_t cliesocklen;          // 本地已知


cfd = socket(AF_INET, SOCK_DGRAM, 0);

//bind(lfd, &clieaddr, cliesocklen);       //(struct sockaddr *)&clieaddr

while(1) {

    // cfd 发送 data 到 servaddr, 传入 servaddr
    len = sendto(cfd, buf, len, 0, &servaddr, servsocklen);   //(struct sockaddr *)&servaddr

    // cfd 接收 data 从 servaddr, 传出 servaddr
    len = recvfrom(cfd, buf, sizeof(buf), 0, &servaddr, &servsocklen); 

    // 显示
}


二、测试程序

1、服务端

#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <string.h>

#define serv_ip     "127.0.0.1"
#define serv_port   6666

int main()
{
	char buf[BUFSIZ];
	char clie_ipbuf[15];
	int n = 0, i = 0;
	int serv_fd;
	struct sockaddr_in serv_addr;      // 设置服务器地址
	struct sockaddr_in clie_addr;      // 待接受客户端地址
	socklen_t clie_addr_len;
	
	//
	serv_fd = socket(AF_INET, SOCK_DGRAM, 0);                                  // 创建socket,  SOCK_DGRAM 报式协议 UDP
	
	// 
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(serv_port);
	inet_pton(AF_INET, serv_ip, &serv_addr.sin_addr.s_addr);
	//serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	bind(serv_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));            // serv_fd 绑定 serv_addr
	
	//
	listen(serv_fd, 128);                                                       // 设置最大同时连接数


	while(1){
		//读取
		memset(buf, 0, sizeof(buf));
		n = recvfrom(serv_fd, buf, sizeof(buf), 0, (struct sockaddr *)&clie_addr, (socklen_t *)&clie_addr_len);
		if(n < 0){
			perror("recvfrom error");
			exit(1);	
		}
		printf("client ip: %s, client port: %d\n", inet_ntop(AF_INET, &clie_addr.sin_addr.s_addr, clie_ipbuf, (socklen_t)sizeof(clie_ipbuf)), ntohs(clie_addr.sin_port));
		printf("%s\n", buf);

		//处理
		for(i=0; i<n; i++)	
		{
			buf[i] = toupper(buf[i]);
		}
        	//回写
		sendto(serv_fd, buf, n, 0, (struct sockaddr *)&clie_addr, (socklen_t)clie_addr_len);
	}

	close(serv_fd);
	printf("server close...\n");

	return 0;
}

2、客户端

#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <string.h>

#define serv_ip     "127.0.0.1"
#define serv_port   6666
#define clie_port   8888                  // 固定端口


int main()
{
	int n = 0;
	char buf[BUFSIZ];
	int clie_fd;
	struct sockaddr_in clie_addr;
	struct sockaddr_in serv_addr;                                     //设置服务器地址
	socklen_t clie_addr_len;
	socklen_t serv_addr_len;


	// socket
	clie_fd = socket(AF_INET, SOCK_DGRAM, 0);                          //创建socket,  SOCK_DGRAM : UDP

	// clie_fd   bind   clie_addr
	clie_addr.sin_family = AF_INET;
	clie_addr.sin_port = htons(clie_port);
	//inet_pton(AF_INET, clie_ip, &clie_addr.sin_addr.s_addr);
	clie_addr.sin_addr.s_addr = htonl(INADDR_ANY);              //
	clie_addr_len = sizeof(clie_addr);
	bind(clie_fd, (struct sockaddr *)&clie_addr, (socklen_t)clie_addr_len);  // clie_fd 绑定 clie_addr

	// serv_addr
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(serv_port);
	//inet_pton(AF_INET, clie_ip, &clie_addr.sin_addr.s_addr);
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);              //
	serv_addr_len = sizeof(serv_addr);

	while(1)
	{
		//从屏幕读
		memset(buf, 0, sizeof(buf));
		fgets(buf, sizeof(buf), stdin);       //fgts()读一行  hello --->   "hello\n\0"
		buf[strlen(buf)-1] = 0;		          //将\n --->  \0
		
		if(strcmp(buf, "quit") == 0) {break;}
		
		n = sendto(clie_fd, buf, strlen(buf), 0, (struct sockaddr *)&serv_addr, serv_addr_len); 
		if(n < 0){
			perror("sendto error");
			exit(1);
		}

		//读取
		memset(buf, 0, sizeof(buf));
		n = recvfrom(clie_fd, buf, sizeof(buf), 0, (struct sockaddr *)&serv_addr, &serv_addr_len); 
		if(n < 0){
			perror("recvfrom error");
			exit(1);
		}

		//打印处理,有问题,可能不是C风格字符串
		printf("%s\n", buf);
	}
	
	close(clie_fd);
	printf("client close...\n");
	
	
	return 0;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值