C语言Windows(socket)UDP注册服务

这个程序实现了基于UDP协议的服务器端用户注册和登录功能。注册时,服务器检查用户名是否已存在,如果不存在则创建文件存储用户信息。登录时,服务器验证用户名和密码的正确性,成功则记录登录信息。程序包含注册、登录两个主要过程,客户端通过发送特定数据包进行交互。
摘要由CSDN通过智能技术生成

服务器端注册程序:

#include <stdio.h>
#include <windows.h>
#include <time.h>
#pragma comment (lib,"ws2_32.lib")

int main()
{
	//初始化
	WSADATA vs;
	WSAStartup(MAKEWORD(2,2),&vs);
	if (HIBYTE(vs.wHighVersion) != 2 || LOBYTE(vs.wVersion) != 2)
	{
		printf("初始化失败!\n"); Sleep(2000); return -1;
	}
	//创建本端socket
	SOCKET udp0 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (udp0 == -1)
	{
		printf("socket创建失败!\n"); Sleep(2000); WSACleanup(); return -1;
	}
	SOCKADDR_IN net0 = { 0 };
	net0.sin_family = AF_INET;
	net0.sin_addr.S_un.S_addr = INADDR_ANY;
	net0.sin_port = htons(4001);
	if (bind(udp0, (SOCKADDR*)&net0, sizeof(net0)) == -1)
	{
		printf("端口启用失败!\n"); Sleep(2000); closesocket(udp0); WSACleanup(); return -1;
	}
	//创建对端网络缓存
	SOCKADDR_IN net1 = { 0 };
	int size_net1 = sizeof(net1);
	printf("等待用户注册:\n");

regist://注册过程
	while (1)
	{
		char data[50] = {0};
		int ret = recvfrom(udp0, data, 50, 0, (SOCKADDR*)&net1, &size_net1);
		if (ret > 0)
		{
			char user[20] = { 0 };
			for (int i = 0; i < 20; i++)
			{
				user[i] = data[i];
				if (user[i] == 0) break;
			}
			//以用户名打开文件,检验文件是否已经存在
			FILE* pf = fopen(user, "r");
			if (pf!= NULL)
			{
				sendto(udp0,"该账号已存在,请直接登录!",30,0,(SOCKADDR*)&net1,sizeof(net1));
				fclose(pf); pf = NULL;
				goto regist;
			}
			//以用户名创建文件,存储用户信息
			FILE* pf1 = fopen(user, "a+");
			fprintf(pf1, "%s\n", user);
			int j = 0;
			char password[20] = { 0 };
			for (int i = 20; i < 40; i++)
			{
				password[j] = data[i];
				if (password[j] == 0) break;
				j++;
			}
			fprintf(pf1, "%s\n", password);
			fclose(pf1); pf1 = NULL;
			sendto(udp0, "注册成功!", 10, 0, (SOCKADDR*)&net1, sizeof(net1));
			time_t rawtime;
			struct tm * timeinfo;
			time(&rawtime);
			timeinfo = localtime(&rawtime);
			
			printf("%s                     %s注册成功!\n", asctime(timeinfo),user);
			//将注册信息写入日志文件
			FILE* info = fopen("regist.info","a+");
			fprintf(info,"%s                      %s注册成功!\n\n", asctime(timeinfo), user);
			fclose(info); info = NULL;
		}
	}
	return 0;
}

服务器端登录程序:

#include <stdio.h>
#include <windows.h>
#pragma comment (lib,"ws2_32.lib")
int main()
{
	//初始化网络
	WSADATA vs;
	WSAStartup(MAKEWORD(2,2),&vs);
	//创建本地socket和信息并绑定
	SOCKET udp0 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	SOCKADDR_IN net0 = { 0 };
	net0.sin_family = AF_INET;
	net0.sin_addr.S_un.S_addr = INADDR_ANY;
	net0.sin_port = htons(4002);
	if(bind(udp0, (SOCKADDR*)&net0, sizeof(net0)) == SOCKET_ERROR)
	{
		printf("端口启用失败!\n"); closesocket(udp0); WSACleanup(); return -1;
	}
	//创建客户端网络信息缓存
	SOCKADDR_IN net1 = { 0 };
	int size_net1 = sizeof(net1);
	printf("等待用户登录:\n");
regist://登录过程
	while (1)
	{
		//接收注册包
		char data[50] = { 0 };
		int ret = recvfrom(udp0,data,50,0,(SOCKADDR*)&net1,&size_net1);
		if (ret > 0)
		{
			FILE* pf = fopen(data,"r");
			if (pf == NULL)
			{
				sendto(udp0,"请先注册!",11,0,(SOCKADDR*)&net1,sizeof(net1));
				goto regist;
			}
			//创建服务器账户密码缓存
			char user[20] = { 0 }, password[20] = { 0 };
			//将账户密码存到数组
			for (int i = 0; i < 20; i++)
			{
				user[i] = fgetc(pf);
				if (user[i] == '\n')
				{
					user[i] = '\0';
					break;
				}
			}
			for (int i = 0; i < 20; i++)
			{
				password[i] = fgetc(pf);
				if (password[i] == '\n')
				{
					password[i] = '\0';
					break;
				}
			}
			fclose(pf); pf = NULL;
			//创建接收到的用户与密码
			char in_user[20] = { 0 };
			char in_password[20] = { 0 };
			//从接收到的数据帧中导入账户密码
			for (int i = 0; i < 20; i++)
			{
				in_user[i] = data[i];
				if (user[i] == '\0')
					break;
			}
			int j = 20;
			for (int i = 0; i < 20; i++)
			{
				in_password[i] = data[j];
				j++;
				if (password[i] == '\0')
					break;
			}
			//比对接收到的账户密码与服务器本地的账户密码关系
			if (strcmp(user, in_user) == 0 && strcmp(password, in_password) == 0)
			{
				
				sendto(udp0,"登录成功!",11,0,(SOCKADDR*)&net1,sizeof(net1));
				FILE* pf1 = fopen("login.info","a+");
				time_t rawtime;
				struct tm * timeinfo;
				time(&rawtime);
				timeinfo = localtime(&rawtime);
				printf("%s           %s登录成功!\n\n", asctime(timeinfo),user);
				//登录信息写入日志
				fprintf(pf1,"%s            %s登录成功!\n\n", asctime(timeinfo), user);
				fclose(pf1); pf1 = NULL;
			}
			else
			{
				printf("%s密码错误!\n",user);
				sendto(udp0, "密码错误!", 11, 0, (SOCKADDR*)&net1, sizeof(net1));
			}
		}
	}
	return 0;
}

注意服务器注册和登录程序需要在同一文件夹!

客户端:

#include <stdio.h>
#include <windows.h>
#include <string.h>
#pragma comment(lib,"ws2_32.lib")
#define password_error -10
#define user_error -9
#define login_success 10
#define regist_success 5
#define server_error -3
int regist()
{
	//初始化网络
	WSADATA vs;
	WSAStartup(MAKEWORD(2,2),&vs);
	if (HIBYTE(vs.wVersion) != 2 || LOBYTE(vs.wVersion) != 2)
	{
		printf("网络初始化失败!\n"); Sleep(2000); return -1;
	}
	//创建本地接口
	SOCKET udp0 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (udp0 == SOCKET_ERROR)
	{
		printf("socket 创建失败!\n"); Sleep(2000); WSACleanup(); return -1;
	}
	//创建服务器网络信息
	SOCKADDR_IN net1 = { 0 };
	net1.sin_family = AF_INET;
	net1.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	net1.sin_port = htons(4001);
	int size_net1 = sizeof(net1);
	//创建账号密码缓存并输入
	char user[50] = {0}, password[50] = { 0 };
	printf("请输入您想要注册的用户名:");
	scanf("%s",user);
	printf("请输入密码:");
	scanf("%s",password);
	if (strlen(user) > 18||strlen(password)>18)
	{
		printf("超过18位,程序退出!"); Sleep(2000); return -1;
	}
	//创建注册包,并将账号密码放入其中
	char regist[50] = { 0 };
	for (int i = 0; i < 20; i++)
	{
		regist[i] = user[i];
		if (regist[i] == 0) break;
	}
	int j = 0;
	for (int i = 20; i < 40; i++)
	{
		regist[i] = password[j];
		if (regist[i] == 0) break;
		j++;
	}
	//发送注册包并等待返回值
	sendto(udp0,regist,50,0,(SOCKADDR*)&net1,size_net1);
	char data[50] = { 0 };
	int ret = recvfrom(udp0, data, 50, 0, (SOCKADDR*)&net1, &size_net1);
	if (ret > 0)
	{
		if (strcmp(data, "该账号已存在,请直接登录!") == 0)
		{
			closesocket(udp0);
			WSACleanup();
			return user_error;
		}

		if (strcmp(data, "注册成功!") == 0) 
		{
			closesocket(udp0);
			WSACleanup();
			return regist_success;
		}
	}
	if (ret < 0)
	{
		return server_error;
	}
	return 0;
}
int login(char user[20],char password[20])
{
	//初始化网络
	WSADATA vs;
	WSAStartup(MAKEWORD(2, 2), &vs);
	if (HIBYTE(vs.wVersion) != 2 || LOBYTE(vs.wVersion) != 2)
	{
		printf("网络初始化失败!\n"); Sleep(2000); return -1;
	}
	//创建本地网络接口
	SOCKET udp0 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (udp0 == SOCKET_ERROR)
	{
		printf("socket创建失败!\n"); WSACleanup(); Sleep(2000); return -1;
	}
	//创建登录服务器网络参数
	SOCKADDR_IN net1 = { 0 };
	net1.sin_family = AF_INET;
	net1.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	net1.sin_port = htons(4002);
	int size_net1 = sizeof(net1);
	//创建登录包,将账号密码放入其中
	char data[50] = { 0 };
	for (int i = 0; i < 20; i++)
	{
		data[i] = user[i];
		if (data[i] == '\0')
			break;
	}
	int j = 0;
	for (int i = 20; i < 40; i++)
	{
		data[i] = password[j];
		j++;
		if (data[i] == '\0')
			break;
	}
	//发送登录包,等待回复
	sendto(udp0, data, 50, 0, (SOCKADDR*)&net1, sizeof(net1));
	char recv_data[50] = { 0 };
	int ret = recvfrom(udp0, recv_data, 50, 0, (SOCKADDR*)&net1, &size_net1);

	if (ret > 0)
	{
		if (strcmp(recv_data, "登录成功!") == 0) return login_success;
		if (strcmp(recv_data, "密码错误!") == 0) return password_error;
		if (strcmp(recv_data, "请先注册!") == 0) return user_error;
	}
	return 0;
}
int chat(char user[20])
{
	printf("%s可以聊天了!\n",user);
	Sleep(2000);


	return 0;
}

int main()
{
	int a = 0, b= 0;
	printf("1.登录   2.注册");
	scanf("%d",&a);
	if (a == 1)
	{
	to_login:;
		char user[20] = { 0 };
		char password[20] = { 0 };
		printf("请输入用户名:");
		scanf("%s",user);
		printf("请输入密码:");
		scanf("%s",password);

		b = login(user,password);
		if (b == user_error)
		{
			printf("请先注册账号\n");
			goto to_regist;
		}
		if (b == password_error)
		{
			printf("密码错误,重新输入\n");
			goto to_login;
		}
		if (b == login_success)
		{
			printf("登录成功!\n");
			chat(user);
			return 0;
		}
	}
	else if (a==2)
	{
to_regist:
		b = regist();
		if (b == user_error)
		{
			printf("账号已经注册过了!请直接登录\n");
			goto to_login;
		}
		if (b == regist_success)
		{
			printf("注册成功!可以登录了\n");
			goto to_login;
		}
	}
	else
	{
		printf("输入错误!\n"); return -1;
	}
	return 0;
}

聊天函数暂时还没写;有时间再弄!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值