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");
}
}