代码如下:
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include<stdio.h>
#include<string.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <curses.h>
#define MAX_SIZE 1024
//用于发起连接
int ConnetServer(char *strName,int port)
{
if(strName == NULL || port <= 0 || port > 65535)
return -1;
struct hostent *phost;
phost = gethostbyname(strName);
if (phost == NULL)
return -1;
struct sockaddr_in sockaddr;
int client;
client = socket(PF_INET, SOCK_STREAM, 0);
if (client < 0)
return -1;
memset(&sockaddr, 0, sizeof(struct sockaddr_in));
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(port);
sockaddr.sin_addr.s_addr = *((long *) phost->h_addr);
// int TimeOut = 2000;
// setsockopt(client,SOL_SOCKET,SO_RCVTIMEO,(char*)&TimeOut,sizeof(TimeOut));
if (connect(client, (struct sockaddr *) &sockaddr, sizeof(struct sockaddr_in)) < 0)
{
close(client);
return -1;
}
return client;
}
// 用于接收数据
int RecvMessage(int client, char *buf, int size)
{
int n = recv(client, buf, size, 0);
if(n < 0)
return -1;
buf[n] = '\0';
return n;
}
// 用于发送数据
int SendMsg(int s,char *buf,int len)
{
int n = send(s,buf,len,0);
if(n < 0)
return -1;
return n ;
}
// 用于清空资源
void CleanUp(int s)
{
close(s);
}
// 用于输入命令
int GetInput(char *buf, int size)
{
int count = 0;
char c;
while(count < size)
{
c = getchar();
if(c == '\n')
break;
buf[count++] = c;
}
buf[count++] = '\0';
return count;
}
// 用于输入文本
int GetContent(char *buf, int size)
{
int count = 0;
char c;
while(count < size)
{
c = getchar();
buf[count++] = c;
if(c == '\n' && buf[count-2] == '\n')
break;
}
buf[count-1] = '\0';
//printf("%s\n",buf);
return count;
}
// 用于接受服务器端响应信息
int RecvResponse(int s ,char *buf,int size,int type)
{
int len = 0;
if ((len = RecvMessage(s, buf, size)) < 1)
{
printf("\nError....\n");
return 0;
}
else
{
//printf("%s\n",buf);
if(type == 1)
{
if((buf[0] == 'S' || buf[0] == 's')
&& buf[1] ==' '
&& buf[2] == '1'
&& buf[3] == '0'
&& buf[4] == '5'){
// 被信任
return 2;
}
else
return -1;
}
}
return 1;
}
// 打印帮助
void PrintHelp()
{
printf("--- HELP Content ---\n");
printf("Command: q == QRY ---\n");
printf("Command: r == GET---\n");
printf("Command: s == SND---\n");
printf("Command: b == BYE---\n");
printf("Command: c == CHP---\n");
printf("Command: h == HELP---\n\n");
}
// 用于解析回响信息
int AnlysisResponse(char *buf)
{
char dest[6];
int index = 0;
for(; index < 5; index++)
dest[index] = buf[index];
dest[index] = '\0';
if(strcmp(dest,"S 101") == 0)
{
// MESSAGE QUEUE里面MESSAGE的个数
char *p = &buf[index+1];
printf("====Message %d ====\n",atoi(p));
}
else if(strcmp(dest,"S 102") == 0)
{
// 获得MESSAGE的内容
//char *p = &buf[index+1];
printf("%s\n",buf);
return 102;
}
else if(strcmp(dest,"S 103") == 0)
{
// 获得MESSAGE的内容
char *p = &buf[index+1];
printf("%s\n",p);
return 103;
}
else if(strcmp(dest,"S 104") == 0)
{
// 获得MESSAGE的内容
printf("message saved!!!!\n");
}
// 命令执行成功
else if(buf[0] == 'S' || buf[0] == 's')
printf("%s execute success!!!\n",dest);
else if(strcmp(dest,"E 101") == 0)
printf("E 101 need privatilty\n");
else if(strcmp(dest,"E 103") == 0)
printf("E 103 ====Message 0 ====\n");
else if(strcmp(dest,"E 107") == 0)
printf("E 107 server problem!!!!\n");
else if(buf[0] == 'E' || buf[0] == 'e')
printf("%s execute failed!!!\n",dest);
else
printf("Error: not understand command [%s]\n",buf);
return 0;
}
// 用于执行QRY、GET、BYE等命令
void BaseCommand(int s,char *buf)
{
SendMsg(s,buf,strlen(buf));
memset(buf,0,MAX_SIZE);
if(RecvResponse(s,buf,MAX_SIZE,0)==0)
{
printf("Error:Recv response error!!!!\n");
return ;
}
else if(AnlysisResponse(buf) == 102)
{
RecvMessage(s, buf, 2000);
printf("%s",buf);
RecvMessage(s, buf, 2000);
printf("%s",buf);
}
}
// 用于修改密码
void ChpCommand(int s,char *buf)
{
char password[20];
strcpy(password,getpass("New Password:"));
sprintf(buf,"CHP %s\r\n",password);
//printf("%s\n",buf);
SendMsg(s,buf,strlen(buf));
memset(buf,0,MAX_SIZE);
if(RecvResponse(s,buf,MAX_SIZE,0)==0)
{
printf("Error:Recv response error!!!!\n");
return ;
}
AnlysisResponse(buf);
}
// 用于发送命令
void SendCommand(int s,char *buf)
{
char name[20];
char message[2048];
printf("Input Username:");
GetInput(name,16);
sprintf(buf,"SND %s\r\n",name);
SendMsg(s,buf,strlen(buf));
memset(buf,0,MAX_SIZE);
if(RecvResponse(s,buf,MAX_SIZE,0)==0)
{
printf("Error:Recv response error!!!!\n");
return ;
}
else if(AnlysisResponse(buf) == 103)
{
// printf("Input message:");
memset(buf,0,MAX_SIZE);
GetContent(message,2000);
sprintf(buf,"%s\r\n.\r\n",message);
if(SendMsg(s,buf,strlen(buf)) < 0)
return ;
// printf("send:%s\n",buf);
RecvResponse(s,buf,MAX_SIZE,0);
AnlysisResponse(buf);
}
}
// 主函数调度
void main(int argc, char **argv)
{
char buf[MAX_SIZE];
int len = 0;
int s;
char *hostname;//="";// char *hostname="localhost";
int port = 2962;
char name[20];
char password[30];
hostname = argv[1];
// 用于接受控制台输入,格式化成host、port
if(argc < 2 || argc > 3)
{
printf("Error:host [ port ]\n");
return ;
}
if(isdigit(argv[2][0])) {
port = atoi(argv[2]);
}
else{
printf("Error:The port is not a digit,now,use the default port[2962]!!!!!");
}
// 处理登录的问题
s = ConnetServer(hostname,port);
if(s == -1){
printf("\nCan't connect address.....\n");
getchar();
exit(0);
}
else{
printf("\nConnects to server.\n");
// 接受服务器端针对connect的响应信息
// 注意,若协议在连接成功时,服务器端不返回信息,请注释掉下面的语句
RecvResponse(s,buf,MAX_SIZE,0);
}
// 循环的方式,完成首次密码登录
while(1)
{
printf("username:");
GetInput(name,16);
strcpy(password,getpass("Password:"));
sprintf(buf,"IAM %s %s\r\n",name,password);
SendMsg(s,buf,strlen(buf));
len = RecvResponse(s,buf,MAX_SIZE,1);
if(len == 2)
{
printf("user:[%s] login success!!!\n",name);
break;
}
else if(len == -1)
printf("\nusername or password is error,please retype!!!!\n");
else
{
printf("Error: login error and ready to quit!!!!");
return ;
}
}
// 用于获得当前是否有消息
strcpy(buf,"QRY\r\n");
BaseCommand(s,buf);
printf("Welcome to use text chat!!!!\n");
PrintHelp();
// 用户主调度程序
while(1)
{
printf("input your command:>");
GetInput(buf, MAX_SIZE);
if(strcmp(buf,"q") == 0)
{
strcpy(buf,"QRY\r\n");
BaseCommand(s,buf);
}
else if(strcmp(buf,"r") == 0)
{
strcpy(buf,"GET\r\n");
BaseCommand(s,buf);
}
else if(strcmp(buf,"b") == 0)
{
strcpy(buf,"BYE\r\n");
BaseCommand(s,buf);
break;
}
else if(strcmp(buf,"s") == 0)
{
strcpy(buf,"SND");
SendCommand(s,buf);
}
else if(strcmp(buf,"c") == 0)
{
strcpy(buf,"CHP");
ChpCommand(s,buf);
}
else if(strcmp(buf,"h") == 0)
PrintHelp();
else
printf("Error:Your command is not understand!!!!\n");
}
// 用于结束连接
printf("\nDisconnects.\n");
CleanUp(s);
exit(0);
}