您的位置:首页 > 其它

udp聊天室 带有注册功能

2015-04-03 16:20 148 查看
fs:(运行在服务器上的)

main.cpp

#include<WinSock2.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#pragma comment(lib,"ws2_32.lib")
#include"init.h"
#include"deal.h"

UserData *userdata[MaxUser];
int userdatap=-1;

int main()
{

InitData(userdata,MaxUser,userdatap);
int iPort=DEFAULT_PORT;
WSADATA wsaData;
SOCKET sSocket;

int iLen;

int iSend;

int iRecv;

char send_buf[1000];

char recv_buf[BUFFER_LENGTH];

struct sockaddr_in ser,cli;

char response[BUFFER_LENGTH];

printf("----------------------\n");
printf("Server Waiting\n");
printf("----------------------\n");

if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{printf("Failed to load Winsock.\n");return 0;}

sSocket=socket(AF_INET,SOCK_DGRAM,0);
if(sSocket==INVALID_SOCKET){printf("socket()Faild:%d\n",WSAGetLastError());return 0;}

ser.sin_family=AF_INET;
ser.sin_port=htons(iPort);
ser.sin_addr.s_addr=htonl(INADDR_ANY);

if(bind(sSocket,(LPSOCKADDR)&ser,sizeof(ser))==SOCKET_ERROR)
{printf("bind()Faild:%d\n",WSAGetLastError());return 0;}

iLen=sizeof(cli);

memset(recv_buf,0,sizeof(recv_buf));

while(1)
{
//接收数据包 确定cli 表示 cli存有客户端发来的 ip和port
iRecv=recvfrom(sSocket,recv_buf,BUFFER_LENGTH,0,(SOCKADDR*)&cli,&iLen);
if(iRecv==SOCKET_ERROR)
{printf("recvfrom()Faild:%d\n",WSAGetLastError());return 0;}
else if(iRecv==0) break;
else
{// 接收到了正确数据
//printf("Accepted client IP:[%s],port:[%d]\n",inet_ntoa(cli.sin_addr),ntohs(cli.sin_port));
//printf("recv:%s\n",recv_buf);

memset(response,'\0',sizeof(response));
deal(recv_buf,userdata,userdatap,response,inet_ntoa(cli.sin_addr));

//返回的控制信息写在response里
//控制信息的种类有00 01 10 11 12 20 21 30 31
//00注册成功 01 注册失败 10登陆成功 11.12表示登陆失败 20表示一次成功会话 21表示错误会话 30表示成功推出 31表示错误推出
//只有 20成功会话需要广播 21.31不予处理 其他会话只需把原信息发回给客户端即可
int i;
if(response[0]=='2' && response[1]=='0')
{//处理20
for(i=0;i<=userdatap;i++)
{
if(userdata[i]->Log==0)continue;

cli.sin_addr.s_addr=inet_addr(userdata[i]->Ip);
cli.sin_port=htons(DEFAULT_PORTSEND);

MySendMessage(sSocket,response,sizeof(response),(SOCKADDR*)&cli,sizeof(cli));

}
}
else
{
//printf("fa:%s\n",inet_ntoa(cli.sin_addr));
cli.sin_port=htons(DEFAULT_PORTSEND);
MySendMessage(sSocket,response,sizeof(response),(SOCKADDR*)&cli,sizeof(cli));

}
}
}
closesocket(sSocket);
WSACleanup();

return 0;
}init.h
#include<stdlib.h>
#include<string.h>

//for main.cpp(1.cpp)
#define DEFAULT_PORT 5051//FOR RECV
#define DEFAULT_PORTSEND 5052//FOR SEND
#define BUFFER_LENGTH 1000

const bool Debug=0;
#define MaxUser 1000
//--------------------------------------------------------------------------------//
//当程序遇到异常而结束时会示出错误而退出
//--------------------------------------------------------------------------------//
//成员结构信息

#define UserNameLen 20
#define PasswordLen 20
typedef struct
{
char UserName[20];
char Password[20];
bool Log;//是否登陆
char Ip[20];
}
UserData;

//--------------------------------------------------------------------------------//
#define thefile "config.txt"
//初始化用户数据导入
bool InitData(UserData **s,int num,int &p)//成功返回true 发生错误返回false
{
//-----------------------------------------//
//读取文件信息并返回
FILE *fp;
char UserBuf[UserNameLen];
char PassBuf[PasswordLen];

fp=fopen(thefile,"r");
if(!fp)
{
if(Debug) printf("config文件不存在\n");
}
else
{
if(Debug) printf("find config.txt\n");
while(!feof(fp))
{
//fgets(buf,sizeof(buf),fp);
fscanf(fp,"%s",UserBuf);
fscanf(fp,"%s",PassBuf);

if(Debug) printf("[+]User:%s Password:%s\n",UserBuf,PassBuf);
//add
p++;
s[p]=(UserData *)malloc(sizeof(UserData));
if(!s[p]){printf("[+]ERROR:malloc failed!\n");return false;}
strcpy(s[p]->UserName,UserBuf);
strcpy(s[p]->Password,PassBuf);
s[p]->Log=0;
memset(s[p]->Ip,'\0',sizeof(s[p]->Ip));
}
fclose(fp);

}

return true;
}

bool SaveData(UserData **userdata,int userdatap)
{
FILE *fp;
///建立配置文件
fp=fopen(thefile,"w");
if(!fp){printf("[+]ERROR:无法创建config文件!");return false;};

int i;
for(i=0;i<=userdatap;i++)
{
fprintf(fp,"%s %s",userdata[i]->UserName,userdata[i]->Password);
if(i!=userdatap)fprintf(fp,"\n");

}
fclose(fp);
}



deal.h
int findUser(UserData **data,int num,char *name)
{
int i;
for(i=0;i<=num;i++)
{
if(strcmp(name,data[i]->UserName)==0) return i;
}
return -1;

}

void deal(char *str,UserData **data,int &num,char *response,char *ip)
{
char User[UserNameLen];
char Pass[PasswordLen];
//第一位字符是功能号
// 0 注册
// 1 登陆
// 2 会话
// 3 退出
int i,t;
if(str[0]=='0')
{
//注册的消息格式为   0+name+@+password
for(i=1;i<strlen(str);i++)
if(str[i]=='@')break;
str[i]='\0';

strcpy(User,str+1);
strcpy(Pass,str+i+1);

t=findUser(data,num,User);
if(t==-1)
{//该用户名不存在,可以注册
num++;
data[num]=(UserData *)malloc(sizeof(UserData));
if(data[num]==NULL){printf("[+]ERROR:malloc failed\n");exit(1);}
strcpy(data[num]->UserName,User);
strcpy(data[num]->Password,Pass);
data[num]->Log=0;
memset(data[num]->Ip,'\0',sizeof(data[num]->Ip));
printf("%s 用户注册成功\n",User);

//--------------------------------------------------注册完成
//返回成功信息
strcpy(response,"00");//第一位是功能号  第二位是状态号   0表示成功  1表示失败
SaveData(data,num);
}
else
{//fail
printf("%s 用户注册失败\n",User);
//-----------------------------------------------注册失败
strcpy(response,"01");
}

;

}
else if(str[0]=='1')
{

//登陆的消息格式为   1+name+@+password
for(i=1;i<strlen(str);i++)
if(str[i]=='@')break;
str[i]='\0';
//printf("i=%d\n",i);
strcpy(User,str+1);
strcpy(Pass,str+i+1);

t=findUser(data,num,User);
if(t!=-1)
{//找到该用户
//printf("Pass=%s",Pass);
//printf("Pawd=%s",data[t]->Password);
if(strcmp(Pass,data[t]->Password)==0)
{//密码验证成功
printf("%s 登陆成功\n",User);

data[t]->Log=1;
strcpy(data[t]->Ip,ip);

strcpy(response,"10");
}
else
{
printf("%s 登陆密码错误\n",User);
strcpy(response,"11");
}
}
else
{
printf("%s 用户不存在,登陆失败\n",User);
strcpy(response,"12");
}
;
}
else if(str[0]=='2')
{
//会话的消息格式为  2+'name'+'@'+'(message)'
for(i=1;i<strlen(str);i++)
if(str[i]=='@')break;
str[i]='\0';

strcpy(User,str+1);
t=findUser(data,num,User);

if(t!=-1 && strcmp(data[t]->UserName,User)==0 && strcmp(data[t]->Ip,ip)==0)
{
//表示确实是正确用户发来的会话
strcpy(response,"20");
strcat(response,User);
strcat(response,":");
strcat(response,str+i+1);
printf("%s:%s\n",User,str+i+1);
}
else
{
strcpy(response,"21");
printf("非正确用户发来会话,不予处理!\n");
}
}
else if(str[0]=='3')
{

//会话的消息格式为  3+'name'+'@'+'(message)'
for(i=1;i<strlen(str);i++)
if(str[i]=='@')break;
str[i]='\0';

strcpy(User,str+1);
t=findUser(data,num,User);

if(t!=-1 && strcmp(data[t]->UserName,User)==0 && strcmp(data[t]->Ip,ip)==0)
{
//表示确实是正确用户发来的会话
strcpy(response,"30");
data[t]->Log=0;
memset(data[t]->Ip,'\0',sizeof(data[t]->Ip));
printf("%s 退出\n",data[t]->UserName);
}
else
{
strcpy(response,"31");
printf("非正确用户发来会话,不予处理!");
}

}

}

void MySendMessage(int sSocket,char *response,int responseLen,SOCKADDR* cli,int cliLen)
{
int iSend;

iSend=sendto(sSocket,response,responseLen,0,(SOCKADDR*)cli,cliLen);
if(iSend==SOCKET_ERROR)
{
printf("sendto()Failed.:%d\n",WSAGetLastError());
}
else if(iSend==0) ;
else
{
//printf("sendto() succeeded !\n");
printf("----------------------\n");
}

}

config.txt

admin admin
1 1
3 3
1 1234
5 644ad
0 0
6 6

接下来的两个文件运行在客户端上的
fcserver

main.cpp

#include<WinSock2.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#pragma comment(lib,"ws2_32.lib")

#define DEFAULT_PORT 5052//FOR RECV
#define BUFFER_LENGTH 1000

void main()
{
int iPort=DEFAULT_PORT;
WSADATA wsaData;
SOCKET sSocket;

int iLen;

int iSend;

int iRecv;

char send_buf[1000];

char recv_buf[BUFFER_LENGTH];

struct sockaddr_in ser,cli;

printf("----------------------\n");
printf("cServer Waiting\n");
printf("----------------------\n");

if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{printf("Failed to load Winsock.\n");return;}

sSocket=socket(AF_INET,SOCK_DGRAM,0);
if(sSocket==INVALID_SOCKET){printf("socket()Faild:%d\n",WSAGetLastError());return;}

ser.sin_family=AF_INET;
ser.sin_port=htons(iPort);
ser.sin_addr.s_addr=htonl(INADDR_ANY);

if(bind(sSocket,(LPSOCKADDR)&ser,sizeof(ser))==SOCKET_ERROR)
{printf("bind()Faild:%d\n",WSAGetLastError());return;}

iLen=sizeof(cli);

memset(recv_buf,0,sizeof(recv_buf));

while(1)
{
//接收数据包 确定cli 表示 cli存有客户端发来的 ip和port
iRecv=recvfrom(sSocket,recv_buf,BUFFER_LENGTH,0,(SOCKADDR*)&cli,&iLen);
if(iRecv==SOCKET_ERROR)
{printf("recvfrom()Faild:%d\n",WSAGetLastError());return;}
else if(iRecv==0) break;
else
{// 接收到了正确数据
//printf("[+]%s\n",recv_buf);
//控制信息的种类有00 01 10 11 12 20 21 30 31
//00注册成功 01 注册失败 10登陆成功 11.12表示登陆失败 20表示一次成功会话 21表示错误会话 30表示成功推出 31表示错误推出

switch(recv_buf[0])
{
case '0':
if(recv_buf[1]=='0')printf("注册成功\n");
else printf("注册失败\n");
break;

case '1':
if(recv_buf[1]=='0')printf("登陆成功\n");
else printf("登陆失败\n");
break;

case '2':
printf("%s\n",recv_buf+2);
break;
}
}
}
closesocket(sSocket);
WSACleanup();
}

fcclient
main.cpp

#include<WinSock2.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#pragma comment(lib,"ws2_32.lib")

#define DEFAULT_PORT 5051//FOR SEND
#define BUFFER_LENGTH 1024

void MySendMessage(SOCKET sSocket,char *response,int responseLen, struct sockaddr* cli,int cliLen);

void main(int argc,char *argv[])
{
WSADATA wsaData;
SOCKET sClient;
int iPort=DEFAULT_PORT;

int iLen;

int iSend;
int iRecv;

char send_buf[1000];

char recv_buf[BUFFER_LENGTH];

struct sockaddr_in ser;

if(argc<2){printf("usage:client [server IP address]\n");return;}

memset(recv_buf,0,sizeof(recv_buf));
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{
printf("Failed to load winsock.\n");
return ;
}

//建立服务器信息 发送到目标机器
ser.sin_family=AF_INET;
ser.sin_port=htons(iPort);
ser.sin_addr.s_addr=inet_addr(argv[1]);

sClient=socket(AF_INET,SOCK_DGRAM,0);
if(sClient==INVALID_SOCKET)
{printf("socket()Failed:%d\n",WSAGetLastError());return;}

iLen=sizeof(ser);

char user[20],password[20];
char str[100];
bool hasLogin=false;
while(!hasLogin)
{
printf("--------------------------------\n");
printf("0.注册\n");
printf("1.登陆\n");
printf("2.退出\n");
printf("请输入相应的数字:\n>");
scanf("%s",&str);
switch(str[0])
{
case '0':
printf("用户名:");
scanf("%s",user);
printf("密 码:");
scanf("%s",password);

strcpy(send_buf,"0");
strcat(send_buf,user);
strcat(send_buf,"@");
strcat(send_buf,password);

MySendMessage(sClient,send_buf,sizeof(send_buf),(struct sockaddr*)&ser,iLen);

break;
case '1':
hasLogin=1;

printf("用户名:");
scanf("%s",user);
printf("密 码:");
scanf("%s",password);

strcpy(send_buf,"1");
strcat(send_buf,user);
strcat(send_buf,"@");
strcat(send_buf,password);

MySendMessage(sClient,send_buf,sizeof(send_buf),(struct sockaddr*)&ser,iLen);
printf("输入exit退出。\n");
printf("--------------------------------\n");
while(1)
{
printf(">");
scanf("%s",&str);

if(strcmp(str,"exit")!=0)
{
strcpy(send_buf,"2");
strcat(send_buf,user);
strcat(send_buf,"@");
strcat(send_buf,str);

MySendMessage(sClient,send_buf,sizeof(send_buf),(struct sockaddr*)&ser,iLen);
}
else
{
strcpy(send_buf,"3");
strcat(send_buf,user);
strcat(send_buf,"@");
MySendMessage(sClient,send_buf,sizeof(send_buf),(struct sockaddr*)&ser,iLen);
exit(0);
}

}

break;

case '2':

exit(0);

break;

default:
printf("--------------------------------\n");
printf("请输入正确信息");

}

}

closesocket(sClient);
WSACleanup();
}

void MySendMessage(SOCKET sSocket,char *response,int responseLen, struct sockaddr* cli,int cliLen)
{
int iSend;

//int sendto ( socket s , const void * msg, int len, unsigned int flags, const struct sockaddr * to , int tolen ) ;
iSend=sendto(sSocket,response,responseLen,0,(SOCKADDR*)cli,cliLen);
// iSend=sendto(sClient,send_buf,sizeof(send_buf),0,(struct sockaddr*)&ser,iLen);
if(iSend==SOCKET_ERROR)
{
printf("sendto()Failed.:%d\n",WSAGetLastError());
}
else if(iSend==0) ;
else
{
//printf("sendto() succeeded !\n");
printf("----------------------\n");
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: