写一个基于 UDP 的镜子服务器,将客户端发送过来的数据照原样反弹回去。

更多资料请点击:我的目录
本篇仅用于记录自己所学知识及应用,代码仍可优化,仅供参考,如果发现有错误的地方,尽管留言于我,谢谢。

运行结果:
在这里插入图片描述

/*
	server部分:
*/
#include <stdio.h>	
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>

int udpsock;
struct sockaddr_in bindaddr;													//定义ipv4地址结构体变量
struct sockaddr_in otheraddr;

void finish()
{
    
    
	sendto(udpsock,"quit",strlen("quit"),0,(struct sockaddr *)&otheraddr,sizeof(otheraddr));
	close(udpsock);
	exit(0);
}

int main()
{
    
    
	char buf[100];
	char ip[16]={
    
    0};
	int ret;
	
	bzero(&bindaddr,sizeof(bindaddr));
	bindaddr.sin_family=AF_INET;
	bindaddr.sin_addr.s_addr=htonl(INADDR_ANY);  								//绑定自己的ip地址
	bindaddr.sin_port=htons(20000); 											//绑定自己的端口号

	bzero(&otheraddr,sizeof(otheraddr));
	int size=sizeof(otheraddr);
	 
	udpsock=socket(PF_INET,SOCK_DGRAM,0);										//创建udp套接字
	if(udpsock==-1)
	{
    
    
		perror("创建udp套接字!\n");
		return -1;
	}
	
	int on=1;
	setsockopt(udpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));					//设置端口重复使用
	
	ret=bind(udpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));			//绑定ip和端口号
	if(ret==-1)
	{
    
    
		perror("绑定失败!\n");
		return -1;
	}
	
	while(1)
	{
    
    
		signal(SIGINT,finish);
		bzero(buf,100);	
		recvfrom(udpsock,buf,100,0,(struct sockaddr *)&otheraddr,&size);		//接收信息
		if(strstr(buf,"quit")!=NULL)											//判断对方的退出消息
		{
    
    
			printf("对方已退出!\n");
			exit(0);
		}
		printf("ip  %s  端口是 %hu 这个人发送的信息是:%s\n",
				inet_ntop(AF_INET,&(otheraddr.sin_addr.s_addr),ip,sizeof(ip)),
					ntohs(otheraddr.sin_port),buf);

		sendto(udpsock,buf,strlen(buf),0,										//回复消息
				(struct sockaddr *)&otheraddr,size);			
	}
}
/*
	client部分:
*/
#include <stdio.h>	
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <pthread.h>

int udpsock;
pthread_t id;
char ip[16]={
    
    0};

struct sockaddr_in bindaddr;													//定义ipv4地址结构体变量
struct sockaddr_in otheraddr;

void finish()
{
    
    
	sendto(udpsock,"quit",strlen("quit"),0,(struct sockaddr *)&otheraddr,sizeof(otheraddr));
	close(udpsock);
	exit(0);
}

void *fun()
{
    
    
	
	struct sockaddr_in recraddr;
	bzero(&recraddr,sizeof(recraddr));
	int size=sizeof(recraddr);
	
	while(1)
	{
    
    
		char buf[100] = {
    
    0};
		recvfrom(udpsock,buf,100,0,(struct sockaddr *)&recraddr,&size);
		if(strstr(buf,"quit")!=NULL)
		{
    
    
			printf("对方已退出!\n");
			exit(0);
		}
		printf("【%s %hu】:%s\n",inet_ntop(AF_INET,&(recraddr.sin_addr.s_addr),ip,sizeof(ip)),
								ntohs(recraddr.sin_port),buf);
	}
}
int main()
{
    
    
	signal(SIGINT,finish);
	int ret;
	bzero(&bindaddr,sizeof(bindaddr));
	bindaddr.sin_family=AF_INET;
	bindaddr.sin_addr.s_addr=htonl(INADDR_ANY);  							//绑定自己的ip地址
	bindaddr.sin_port=htons(10086); 										//绑定自己的端口号

	
	bzero(&otheraddr,sizeof(otheraddr));
	otheraddr.sin_family=AF_INET;
	otheraddr.sin_addr.s_addr=inet_addr("192.168.1.157"); 					//对方的地址
	otheraddr.sin_port=htons(20000);										//对方的端口号
	 
	
	udpsock=socket(PF_INET,SOCK_DGRAM,0);									//创建udp套接字		
	if(udpsock==-1)
	{
    
    
		perror("创建udp套接字!\n");
		return -1;
	}
	
	int on=1;
	setsockopt(udpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));				//设置端口重复使用
	
	ret=bind(udpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));		//绑定ip和端口号
	if(ret==-1)
	{
    
    
		perror("绑定失败!\n");
		return -1;
	}
	printf("请输入信息:\n");
	pthread_create(&id, NULL , &fun ,NULL);

	while(1)
	{
    
    
		char buf[100] = {
    
    0};
		scanf("%s",buf);
		sendto(udpsock,buf,strlen(buf),0,(struct sockaddr *)&otheraddr,sizeof(otheraddr));
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43793181/article/details/108524134