1、编号 TCP/IP合同与网络编程 期末大作业 题目: 基于Socket网络通信 物联网工程 学院 计算机科学与技术 专业 摘 要 课题是基于TCP/UDP合同编写聊天室系统。聊天室系统重要涉及注册、登陆、群聊、单聊、显示在线人员和退出功能。系统重要涉及客户端、服务器端和客户显示端。其中客户端与服务器端连接基于TCP合同,服务器端向客户显示端发送数据是基于UDP合同。 课题是网络合同栈中传播层应用,在
2、网络成基本上,在传播层中使用网络套接字,达到数据传送目,从而实现聊天室系统功能。 核心词:TCP/UDP;聊天室;网络套接字;数据传送 目录 第1章 总体设计 2 第2章 客户端设计 3 2.1 发送端设计 3 2.11 流程图 3 2.12 代码 3 2.2接受端设计 3 2.21 流程图 3 2.22 代码 3 第3章 服务器设计 4 3.1 流程图 4 3.2 代码 4 第4章 运营成果 5 第1章 总体设计 1 原理 1.1 TCP 在面向连接数据流(SOCK_STREAM)传播过程中,设计基于TCP/IP合同程序是传播层使用TC
3、P合同,它最大特点是在通信之前要在客户和服务器之间先建立连接,在数据传播完毕后要关闭连接,释放网络资源。 面向连接客户/服务器程序工作模型如下: 1.2 UDP 无连接数据报(SOCK_DGRAM)传播服务在传播层使用合同时UDP合同。与面向连接通信合同过程不同,它最大特点就是必要要在客户和服务器之间建立连接,通信任何一方可以先发送数据,这样一方面发送数据一方就成为客户端,而接受数据一方就是服务器端。在数据传播完毕后,只要关闭套接口,释放网络资源,通信过程就结束了。 无连接数据包传播服务通信是,客户端与服务器端所使用函数是类似。 面向无连接客户/服务器程序工作模型如下:
4、
1.3 流程图
基于TCP/UDP聊天室系统涉及客户端、客户显示端和服务器端三某些。功能重要是注册、登陆、群聊、单聊、显示在线人员和退出。客户端与服务器端连接合同基于TCP合同,服务器端发送功能基于UDP合同。客户端与服务器端建立连接后,客户端进行操作,将数据发送至客户显示端。
第2章 客户端设计
2.11 流程图
2.12 代码
#include
5、ZE 1024 void MySendMessage(SOCKET sSocket,char *response,int responseLen); int main(int argc, char **argv) { WSADATA wsaData; sockaddr_in ser,cli; SOCKET sClient,wchysClient; int iLen,wchyiLen; int iRecv; char send_buf[1000]; char recv_buf[BUFFER_SIZE]; if (WSAStartup(M
6、AKEWORD(2, 2), &wsaData) != 0) { printf("WSAStartup()\n"); return 0; } printf("手动连接模式中....\n"); char szServer[256]; //连接服务器地址,IP地址 printf("请输入即将连接服务器IP地址:"); gets(szServer); ser.sin_family = AF_INET; ser.sin_port = htons(5050); ser.sin_addr.s_addr = inet_addr(szServer
7、); char user[20],password[20]; char str[100],str1[100],wchystr[100]; bool hasLogin=false; //只能绑定一次,开始放在了循环里,555 wchysClient=socket(AF_INET,SOCK_DGRAM,0); if(wchysClient==INVALID_SOCKET){printf("socket()Faild:%d\n",WSAGetLastError());return 0;} cli.sin_family=AF_INET; cli.sin_port
8、htons(5053); cli.sin_addr.s_addr=htonl(INADDR_ANY); if(bind(wchysClient,(LPSOCKADDR)&cli,sizeof(cli))==SOCKET_ERROR) {printf("bind()Faild:%d\n",WSAGetLastError());return 0;} wchyiLen=sizeof(cli); memset(recv_buf,0,sizeof(recv_buf)); sClient = socket(AF_INET, SOCK_STREAM,
9、0); if (sClient == INVALID_SOCKET) { printf("socket()\n"); return 0; } if (connect(sClient, (sockaddr*)&ser, sizeof(ser)) == INVALID_SOCKET) { printf("socket()\n"); return 0; } else { bool hasLogin=false; while(!hasLogin){ printf("----------------------------
10、\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"); strca
11、t(send_buf,user); strcat(send_buf,"@"); strcat(send_buf,password); MySendMessage(sClient, send_buf, sizeof(send_buf)); break; case '1': printf("顾客名:"); scanf("%s",user); printf("密 码:"); scanf("%s",password); strcpy(send_buf,
12、"1"); strcat(send_buf,user); strcat(send_buf,"@"); strcat(send_buf,password); MySendMessage(sClient, send_buf, sizeof(send_buf)); iRecv=recvfrom(wchysClient,recv_buf,BUFFER_SIZE,0,(SOCKADDR*)&cli,&wchyiLen); if(iRecv==SOCKET_ERROR) {printf("recvfr
13、om()Faild:%d\n",WSAGetLastError());return 0;} else if(iRecv==0) break; else {// 接受到了对的数据 printf("recv:%s\n",recv_buf); } if(recv_buf[0]=='@'&&recv_buf[1]=='@'){ hasLogin=0; system("cls"); printf("登录失败!请重新登录或注册后登录^_^\n"); } if(recv_buf
14、[0]=='*'&&recv_buf[1]=='*'){ hasLogin=0; system("cls"); printf("已经在其她地方登陆\n"); printf("登录失败!请重新选取顾客登录或注册后登录^_^\n"); } if(recv_buf[0]=='#'&&recv_buf[1]=='#'){ hasLogin=1; system("cls"); printf("登录成功^_^\n"); bool wchyhasLogin=false;
15、 while(!wchyhasLogin){ printf("--------------------------------\n"); printf("0.群聊\n"); printf("1.单聊\n"); printf("2.在线顾客\n"); printf("3.退出\n"); printf("请输入相应数字:\n>"); scanf("%s",&wchystr); switch(wchystr[0]) { case '0':
16、 wchyhasLogin=1; printf("输入exit退出。\n"); printf("--------------------------------\n"); while(wchyhasLogin) { printf(">"); scanf("%s",&str); if(strcmp(str,"exit")!=0) { strcpy(send_buf,"2"); strcat(se
17、nd_buf,user); strcat(send_buf,"@"); strcat(send_buf,str); MySendMessage(sClient, send_buf, sizeof(send_buf)); } else { system("cls"); wchyhasLogin=0; } } break; case '1': w
18、chyhasLogin=1; printf("请输入单聊对象顾客名:"); scanf("%s",&str1); strcpy(send_buf,"5"); strcat(send_buf,str1); strcat(send_buf,"@"); strcat(send_buf,user); strcat(send_buf,"*"); strcat(send_buf,"__Welcome__To__Single__Chat...");
19、 MySendMessage(sClient, send_buf, sizeof(send_buf)); iRecv=recvfrom(wchysClient,recv_buf,BUFFER_SIZE,0,(SOCKADDR*)&cli,&wchyiLen); if(iRecv==SOCKET_ERROR) {printf("recvfrom()Faild:%d\n",WSAGetLastError());return 0;} else if(iRecv==0) break; e
20、lse {// 接受到了对的数据 //printf("recv:%s\n",recv_buf); } if(recv_buf[0]=='^'&&recv_buf[1]=='^'){ wchyhasLogin=0; system("cls"); printf("单聊对象不存在,退出了单聊模式\n"); } if(recv_buf[0]=='&'&&recv_buf[1]=='&'){ wchyhasLogin
21、0; system("cls"); printf("单聊对象未在线,退出了单聊模式\n"); } if(recv_buf[0]=='%'&&recv_buf[1]=='%'){ printf("输入exit退出。\n"); printf("--------------------------------\n"); while(wchyhasLogin) { printf(">");
22、 scanf("%s",&str); if(strcmp(str,"exit")!=0) { strcpy(send_buf,"5"); strcat(send_buf,str1); strcat(send_buf,"@"); strcat(send_buf,user); strcat(send_buf,"*"); strcat(send_buf,str);
23、 MySendMessage(sClient, send_buf, sizeof(send_buf)); } else { system("cls"); wchyhasLogin=0; } } } break; case '2': strcpy(send_buf,"4"); strcat(send_buf,user); strcat(send_buf,"@"
24、); strcat(send_buf,str); MySendMessage(sClient, send_buf, sizeof(send_buf)); system("cls"); break; case '3': strcpy(send_buf,"3"); strcat(send_buf,user); strcat(send_buf,"@"); MySendMessage(sClient, send_buf, sizeof(send
25、buf)); hasLogin=0; wchyhasLogin=1; system("cls"); break; default: system("cls"); printf("请输入对的信息\n"); break; } } } break; case '2': exit(0); break; default: system("cls"); printf
26、"请输入对的信息"); } } } system("PAUSE"); closesocket(sClient); WSACleanup(); return 0; } void MySendMessage(SOCKET sSocket,char *response,int responseLen) { int iSend; iSend=send(sSocket,response,responseLen,0); if(iSend==SOCKET_ERROR) { printf("send()Failed.:%d\n
27、",WSAGetLastError());
}
else if(iSend==0) ;
else
{
//printf("send() succeeded !\n");
printf("----------------------\n");
}
}
2.2接受端设计
2.21 流程图
2.22 代码
#include
28、SEND 5052//FOR SEND #define BUFFER_LENGTH 1000 const bool Debug=0; #define MaxUser 1000 //--------------------------------------------------------------------------------// //当程序遇到异常而结束时会示出错误而退出 //--------------------------------------------------------------------------------// //成员构造信息
29、 #define UserNameLen 200 #define PasswordLen 200 typedef struct { char UserName[200]; char Password[200]; bool Log;//与否登陆 char Ip[20]; } UserData; #define thefile "config.txt" bool SaveData(UserData **userdata,int userdatap); //------------------------------------------------------
30、// //初始化顾客数据导入 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[UserN
31、ameLen];
char Pass[PasswordLen];
//第一位字符是功能号
// 0 注册
// 1 登陆
// 2 会话
// 3 退出
int i,t;
if(str[0]=='0')
{
//注册消息格式为 0+name+@+password
for(i=1;i 32、um,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 33、',sizeof(data[num]->Ip));
printf("%s 顾客注册成功\n",User);
//--------------------------------------------------注册完毕
//返回成功信息
strcpy(response,"00");//第一位是功能号 第二位是状态号 0表达到功 1表达失败
SaveData(data,num);
}
else
{//fail
printf("%s 顾客注册失败\n",User);
//-------------------- 34、注册失败
strcpy(response,"01");
}
}
else if(str[0]=='1')
{
//登陆消息格式为 1+name+@+password
for(i=1;i 35、m,User);
if(t!=-1)
{//找到该顾客
//printf("Pass=%s",Pass);
//printf("Pawd=%s",data[t]->Password);
if(strcmp(Pass,data[t]->Password)==0 && data[t]->Log==0)
{//密码验证成功
printf("%s 登陆成功\n",User);
data[t]->Log=1;
strcpy(data[t]->Ip,ip);
strcpy(response,"10");
} 36、
else if(strcmp(Pass,data[t]->Password)==0 && data[t]->Log==1){
printf("%s 已经在其她地方登陆\n",User);
strcpy(response,"1@");
}
else
{
printf("%s 登陆密码错误\n",User);
strcpy(response,"11");
}
}
else
{
printf("%s 顾客不存在,登陆失败\n",User);
strcpy(response,"12"); 37、
}
}
else if(str[0]=='2')
{
//会话消息格式为 2+'name'+'@'+'(message)'
for(i=1;i 38、对的顾客发来会话
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'+'@'+'( 39、message)'
for(i=1;i 40、data[t]->Ip,'\0',sizeof(data[t]->Ip));
printf("%s 退出\n",data[t]->UserName);
}
else
{
strcpy(response,"31");
printf("非对的顾客发来会话,不予解决!");
}
}
else if(str[0]=='4')
{
for(i=1;i 41、");
for(i=0;i<=num;i++)
{
if(data[i]->Log==1){
printf("%s[%s]在线\n",data[i]->UserName,data[i]->Ip);
//printf("%s\n",data[i]->UserName);
strcat(response,data[i]->UserName);
strcat(response," ");
}
else{
//printf("%s",data[i]->Ip);
}
}
}
else i 42、f(str[0]=='5')
{
for(i=1;i 43、
t=findUser(data,num,User);
if(t==-1)
{
strcpy(response,"60");
printf("单聊对象不存在");
}
else
{
if(data[t]->Log==0)
{
strcpy(response,"61");
printf("%s 未在线\n",User);
}
else if(data[t]->Log==1){
strcpy(response,"50");
strcat( 44、response,Pass);
strcat(response,":");
strcat(response,Pass+i+1);
printf("%s:%s\n",Pass,Pass+i+1);
printf("%s 在线,可进行聊天\n",User);
}
}
}
}
void MySendMessage(int sSocket,char *response,int responseLen,SOCKADDR* cli,int cliLen)
{
int iSend;
iSend 45、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");
}
}
bool InitData(UserDat 46、a **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 47、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:mal 48、loc 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;
///建立配 49、备文献
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);
}
#include 50、dlib.h>
#include






