wlbcday4

该代码展示了使用UDP套接字进行广播、多播以及文件上传下载的基本操作。程序包含了错误处理宏定义,用于在发生错误时打印行号和错误信息。通过创建不同类型的套接字,设置广播选项,加入多播组,以及处理用户输入和数据收发,实现了简单的网络通信功能。
摘要由CSDN通过智能技术生成
#include <myhead.h>
 
#define ERR_MSG(msg) do{\
	fprintf(stderr, "__%d__\n", __LINE__);\
	perror("msg");\
}while(0)
 
#define IP "192.168.123.255"
#define PORT 8888
 
int main(int argc, const char *argv[])
{
	//创建套接字
	int sfd = socket(AF_INET, SOCK_DGRAM, 0);
	if (sfd < 0)
	{
		ERR_MSG("socket");
		return -1;
	}
 
 
 
	//设置允许广播
	int broad = 1;
	if (setsockopt(sfd, SOL_SOCKET, SO_BROADCAST, (void *)&broad, sizeof(broad)) < 0)
	{
		ERR_MSG("setsockopt");
		return -1;
	}
 
 
 
	//存储接收方信息
	struct sockaddr_in sin;
	sin.sin_family      = AF_INET;
	sin.sin_addr.s_addr = inet_addr(IP);
	sin.sin_port        = htons(PORT);
 
 
 
	char buf[128] = "";
	//发送信息
	while(1)
	{
		bzero(buf, sizeof(buf));
 
		fgets(buf, sizeof(buf), stdin);
		buf[strlen(buf) - 1] = '\0';
 
		if (sendto(sfd, buf, sizeof(buf), 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
		{
			ERR_MSG("sendto");
			return -1;
		}
	}
 
	close(sfd);
 
	return 0;
}
#include <myhead.h>
 
#define ERR_MSG(msg) do{\
	fprintf(stderr, "__%d__\n", __LINE__);\
	perror("msg");\
}while(0)
 
#define IP "192.168.123.255"
#define PORT 8888
 
int main(int argc, const char *argv[])
{
	//创建套接字
	int sfd = socket(AF_INET, SOCK_DGRAM, 0);
	if (sfd < 0)
	{
		ERR_MSG("socket");
		return -1;
	}
 
 
 
	//绑定发送方信息
	struct sockaddr_in sin;
	sin.sin_family      = AF_INET;
	sin.sin_port        = htons(PORT);
	sin.sin_addr.s_addr = inet_addr(IP);
 
 
 
	if (bind(sfd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
	{
		ERR_MSG("bind");
		return -1;
	}
 
 
 
	char buf[128] = "";
	//接收信息
	while(1)
	{
		bzero(buf, sizeof(buf));
 
		if (recvfrom(sfd, buf, sizeof(buf), 0, NULL, NULL) < 0)
		{
			ERR_MSG("sendto");
			return -1;
		}
		printf(": %s\n", buf);
	}
 
	close(sfd);
 
	return 0;
}
#include <myhead.h>
 
#define ERR_MSG(msg) do{\
	fprintf(stderr, "__%d__\n", __LINE__);\
	perror("msg");\
}while(0)
 
#define IP "224.10.2.3"
#define PORT 6666
 
int main(int argc, const char *argv[])
{
	//创建套接字
	int sfd = socket(AF_INET, SOCK_DGRAM, 0);
	if (sfd < 0)
	{
		ERR_MSG("socket");
		return -1;
	}
 
 
 
	//存储接收方信息
	struct sockaddr_in sin;
	sin.sin_family      = AF_INET;
	sin.sin_port        = htons(PORT);
	sin.sin_addr.s_addr = inet_addr(IP);
 
 
 
	char buf[128] = "";
	while(1)
	{
		bzero(buf,sizeof(buf));
		fgets(buf, sizeof(buf), stdin);
		buf[strlen(buf) - 1] = '\0';
		//发送信息
		if (sendto(sfd, buf, sizeof(buf), 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
		{
			ERR_MSG("sendto");
			return -1;
		}
		printf("发送成功\n");
	}
 
	close(sfd);
	
	return 0;
}
#include <myhead.h>
 
#define ERR_MSG(msg) do{\
	fprintf(stderr, "__%d__\n", __LINE__);\
	perror("msg");\
}while(0)
 
#define zb_IP "224.1.2.3"
#define loc_IP "192.168.122.221"
#define PORT 8888
 
int main(int argc, const char *argv[])
{
	//创建套接字
	int sfd = socket(AF_INET, SOCK_DGRAM, 0);
	if (sfd < 0)
	{
		ERR_MSG("socket");
		return -1;
	}
 
 
 
	//设置组播
	struct ip_mreqn mq;
	mq.imr_multiaddr.s_addr = inet_addr(zb_IP);
	mq.imr_address.s_addr   = inet_addr(loc_IP);
	mq.imr_ifindex          = 2;	
	if (setsockopt(sfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mq, sizeof(mq)) < 0)
	{
		ERR_MSG("setsockopt");
		return -1;
	}
 
 
 
 
	//存储发送方信息
	struct sockaddr_in sin;
	sin.sin_family      = AF_INET;
	sin.sin_port        = htons(PORT);
	sin.sin_addr.s_addr = inet_addr(loc_IP);
 
 
 
	char buf[128] = "";
	while(1)
	{
		//接收信息
		if (recvfrom(sfd, buf, sizeof(buf), 0, NULL, NULL) < 0)
		{
			ERR_MSG("recvfrom");
			return -1;
		}
	
	}
 
	close(sfd);
	
	return 0;
}
#include <myhead.h>
 
#define ERR_MSG(msg) do{\
	fprintf(stderr, "line:%d\n", __LINE__);\
	perror(msg);\
}while(0)
 
#define IP "192.168.123.111"
#define PORT 69
 
int do_download(int cfd,struct sockaddr_in sin);
 
int do_upload(int cfd, struct sockaddr_in sin);
 
int main(int argc, const char *argv[])
{
   //创建报式套接字
	int cfd = socket(AF_INET, SOCK_DGRAM, 0);
	if (cfd < 0)
	{
		ERR_MSG("socket");	
		return -1;
	}
	printf("cfd = %d\n", cfd);
 
 
 
   //填充服务器的地址信息结构体
	struct sockaddr_in sin;
	sin.sin_family      = AF_INET;        
	sin.sin_port        = htons(PORT);   
	sin.sin_addr.s_addr = inet_addr(IP);   
	
	
	
	char c = 0;
	while (1)
	{
 
		printf("请选择:\n\t 1>下载\n\t 2>上传\n\t 3>退出\n");
 
		c = getchar();
		while (getchar() != 10)
 
		printf("%c\n",c);
		switch (c)
		{
			case '1':
				do_download(cfd, sin);
				break;
			case '2':
				 do_upload(cfd, sin);
				break;
			case '3':
				goto END;
			default:
				printf("输入错误,请重新输入:\n");
		}
 
	}
 
 
 
END:
	//关闭文件描述符
	close(cfd);
 
	return 0;
}
int do_download(int cfd,struct sockaddr_in sin)
{
   	char name[20] = "";
	printf("请输入文件名:");
	scanf("%s", name);
	while(getchar() != 10);
 
 
 
	//组数据包
	char buf[516] = "";
 
	unsigned short *ptr1 = (unsigned short *)buf;
	*ptr1 = htons(1);
 
	char *ptr2 = buf + 2;
	strcpy(ptr2, name);
 
	char *ptr3 = ptr2 + strlen(name);
	*ptr3 = 0;
 
	char *ptr4 = ptr3 + 1;
	strcpy(ptr4, "octet");
 
	int size = 2 + 2 + 1 + strlen(ptr2) + strlen(ptr4);
 
 
 
    //发送下载请求给服务器
	if (sendto(cfd, buf, size, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
	{
		ERR_MSG("sendto 下载请求");
		return -1;
	}
	printf("发送下载请求给服务器成功\n");
 
 
 
    //打开一个用于写入的文件
    int fd = open(ptr2, O_WRONLY|O_CREAT|O_APPEND, 0664);
    if(fd < 0)
	{
        ERR_MSG("fd err");
		return -1;
	}
 
 
 
    while(1)
	{
		bzero(buf, sizeof(buf));
		socklen_t addlen = sizeof(sin);
		int res = 0;
		if((res = recvfrom(cfd, buf, sizeof(buf), 0, (struct sockaddr *)&sin, &addlen)) < -1)
		{
			ERR_MSG("recvfrom");
			return -1;
		}
 
 
 
		//写入本地
		char *data = buf + 4;
		write(fd, data, 512);
 
 
 
		//组ACK包
		unsigned short net = *(ptr1 + 1);
		bzero(buf, sizeof(buf));
		*ptr1 = htons(4);
		*(ptr1 + 1) = net;
 
 
 
		//回复ACK
		if(sendto(cfd, buf, 4, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
		{
			ERR_MSG("sendto");
			return -1;
		}
 
 
 
		//判断数据是否小于512,若小于512,则传输结束
		if(res<516)
			break;
 
	}
 
    close(fd);
    return -1;
}
 
 
 
int do_upload(int cfd, struct sockaddr_in sin)
{
    char name[20] = "";
	printf("请输入文件名:");
	scanf("%s", name);
	while(getchar() != 10);
 
 
 
    //组数据包
	char buf[516] = "";
 
	unsigned short *ptr1 = (unsigned short *)buf;
	*ptr1 = htons(2);
 
	char *ptr2 = buf + 2;
	strcpy(ptr2, name);
 
	char *ptr3 = ptr2 + strlen(name);
	*ptr3 = 0;
 
	char *ptr4 = ptr3 + 1;
	strcpy(ptr4, "octet");
 
	int size = 2 + 2 + 1 + strlen(ptr2) + strlen(ptr4);
 
 
 
    //发送上传请求给服务器
	if (sendto(cfd, buf, size, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
	{
		ERR_MSG("sendto 上传请求");
		return -1;
	}
	printf("发送上传请求给服务器成功\n");
 
 
 
    // 获取服务器的临时端口
    struct sockaddr_in tem_sin;
    socklen_t addrlen = sizeof(tem_sin);
 
 
 
    // 接收服务器发来的包
    bzero(buf, sizeof(buf));
    if (recvfrom(cfd, buf, sizeof(buf), 0, (struct sockaddr*)&tem_sin, &addrlen) < 0) 
	{
        ERR_MSG("recvfrom error");
    }
 
 
 
    // 打开上传的文件
	int fd = open("./1.c", O_RDONLY);
    if (fd < 0) 
	{
        ERR_MSG("open error");
        return -1;
    }
 
 
 
    while (1) 
	{
		unsigned short net = *(ptr1 + 1);
        bzero(buf, sizeof(buf));
        // 组数据包
		*ptr1 = htons(3);
		*(ptr1 + 1) = net;
 
 
 
		int res = 0;
        // 发送数据包
        res = sendto(cfd, buf, sizeof(buf), 0, (struct sockaddr*)&tem_sin, sizeof(tem_sin));
        if (res < 0) 
		{
            ERR_MSG("sendto error");
            return -1;
        }
 
 
 
		//判断数据是否小于512,若小于512,则传输结束
		if(res<516)
			break;
 
 
 
        // 接收并检验服务器发来的包
        bzero(buf, sizeof(buf));
        if (recvfrom(cfd, buf, sizeof(buf), 0, (struct sockaddr*)&tem_sin, &addrlen) < 0) 
		{
            ERR_MSG("recvfrom error");
            return -1;
        }
    }
    return 0;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值