TCPIP大作业-基于TCP的网络通信编程C语言版(江南大学).doc_第1页
TCPIP大作业-基于TCP的网络通信编程C语言版(江南大学).doc_第2页
免费预览已结束,剩余42页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

tcp/ip协议编程大作业课题名称 基于tcp的网络通信 专 业 计算机科学与技术 班 级 计算机1206 学 号 学生姓名 物联网工程学院摘 要此tcp/ip课程设计实现了基于tcp的客户/服务器通信程序,具体实验过程通过有连接服务为主体,无连接服务为辅并利用事件对象i/o管理来实现。客户机具有注册,登陆,单聊,私聊,在线人数列表,退出等功能。目 录一、 总体设计41、基本通信协议选取42、通信过程设计43、通信过程数据包设计44、 程序流程图5二、 客户端程序61、功能:62、原理:63、程序清单6三、 服务器端程序191、功能:192、原理:193、程序清单:19四、 运行结果351、 服务器端截图352、客户端截图371、 总体设计1、基本通信协议选取tcp (transmission control protocol)和udp(user datagram protocol)协议属于传输层协议。tcp提供ip环境下的数据可靠传输,它提供的服务包括数据流传送、可靠性、有效流控、全双工操作和多路复用。通过面向连接、端到端和可靠的数据包发送。而udp则不为ip提供可靠性、流控或差错恢复功能。tcp对应的是可靠性要求高的应用,而udp对应的则是可靠性要求低、传输经济的应用。本次实验基于tcp/ip协议利用事件对象i/o管理实现基本的聊天功能,包括注册,登录,群聊,私聊及在线人数统计。2、通信过程设计2.1客户端设计a. 本地服务器主要功能:1)接收远程服务器转发的消息并显示消息。b. 本地客户端主要功能:1)发送建立tcp连接的请求操作;2)发送注册信息,登陆消息及退出请求;3)发送群聊消息,私聊消息,在线人数统计及退出请求。2.2服务器端设计a. 远程服务端主要功能:1)监听客户端的连接请求;2)提供注册服务,验证登陆请求和验证功能;3)查看在线人数,发送在线状态;4)发送群聊消息及私聊消息。3、通信过程数据包设计3.1客户端数据包设计:a.注册:0user(用户名)password(密码)b.登陆:1user(用户名)password(密码)c.聊天:0)群聊:2user(用户名)str(内容)1)单聊:5str1(单聊对象名)user(用户名)*str(内容)2)在线用户4user(用户名)str(内容)3)退出(登录):3user(用户名)3.2服务端数据包设计:a.注册应答:00注册成功01注册失败用户名已存在b.登陆应答:10登陆成功12用户名不存在11密码不正确1该用户已登陆c.聊天:1)单聊:61单聊对象不在线50单聊对象在线60单聊对象不存在2)群聊:30广播消息31非正确用户的消息,不广播3)在线人数:40显示当前在线人数并发给查询客户4、 程序流程图2、 客户端程序1、功能:1.1注册:向服务器发送注册信息。然后接收服务器返回的应答信息。1.2登陆:向服务器发送登陆信息。接收服务器返回的应答信息。1.3聊天:登陆成功后,选择群聊或单聊进行聊天,选择在线用户可进行查询当前在线用户,选择退出可退出登录。a.单聊:从在线用户中选择一个,与其单聊b.群聊:向所有在线的用户发送消息c.退出聊天:退出此次聊天,但不断开连接d.退出登陆,断开连接,退出时不需要发送下线信息,直接退出1.4面向连接的客户/服务器程序工作模型:2、原理:客户机在注册或登陆时首先和服务器连接,注册完或登陆失败断开连接,登陆成功不断开连接,使用send和recv发送接收数据,根据上述的数据报的定义,发送相应的数据报。3、程序清单3.1客户端接收器(本地服务器)代码#include#include#include#include#pragma comment(lib,ws2_32.lib)#define default_port 5051/for recv#define buffer_length 1000void mysendmessage(socket ssocket,char *response,int responselen, struct sockaddr* cli,int clilen);void main()int iport=default_port;wsadata wsadata;socket ssocket,wchyssocket;int ilen,wchyilen;int isend;int irecv;char send_buf1000;char recv_bufbuffer_length;struct sockaddr_in ser,cli,wchy;printf(-n);printf(cserver waitingn);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:%dn,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:%dn,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:%dn,wsagetlasterror();return;else if(irecv=0) break;else / 接收到了正确数据/printf(+%sn,recv_buf);/控制信息的种类有00 01 10 11 12 20 21 30 31/00注册成功 01 注册失败 10登陆成功 11.12表示登陆失败 20表示一次成功会话 21表示错误会话 30表示成功推出 31表示错误推出switch(recv_buf0)case 0:if(recv_buf1=0)printf(注册成功n);else printf(注册失败n);break;case 1:if(recv_buf1=0)printf(登陆成功n);wchy.sin_family=af_inet;wchy.sin_port=htons(5053);wchy.sin_addr.s_addr=inet_addr(127.0.0.1);wchyssocket=socket(af_inet,sock_dgram,0);if(wchyssocket=invalid_socket)printf(socket()failed:%dn,wsagetlasterror();return;wchyilen=sizeof(wchy);strcpy(send_buf,#);mysendmessage(wchyssocket,send_buf,sizeof(send_buf),(struct sockaddr*)&wchy,wchyilen);else if(recv_buf1=)printf(已经在其他地方登陆n);wchy.sin_family=af_inet;wchy.sin_port=htons(5053);wchy.sin_addr.s_addr=inet_addr(127.0.0.1);wchyssocket=socket(af_inet,sock_dgram,0);if(wchyssocket=invalid_socket)printf(socket()failed:%dn,wsagetlasterror();return;wchyilen=sizeof(wchy);strcpy(send_buf,*);mysendmessage(wchyssocket,send_buf,sizeof(send_buf),(struct sockaddr*)&wchy,wchyilen);elseprintf(登陆失败n);wchy.sin_family=af_inet;wchy.sin_port=htons(5053);wchy.sin_addr.s_addr=inet_addr(127.0.0.1);wchyssocket=socket(af_inet,sock_dgram,0);if(wchyssocket=invalid_socket)printf(socket()failed:%dn,wsagetlasterror();return;wchyilen=sizeof(wchy);strcpy(send_buf,);mysendmessage(wchyssocket,send_buf,sizeof(send_buf),(struct sockaddr*)&wchy,wchyilen);break;case 2:printf(群聊%sn,recv_buf+2);break;case 4:printf(在线用户列表:%sn,recv_buf+2);break;case 5:printf(单聊);wchy.sin_family=af_inet;wchy.sin_port=htons(5053);wchy.sin_addr.s_addr=inet_addr(127.0.0.1);wchyssocket=socket(af_inet,sock_dgram,0);if(wchyssocket=invalid_socket)printf(socket()failed:%dn,wsagetlasterror();return;wchyilen=sizeof(wchy);strcpy(send_buf,%);mysendmessage(wchyssocket,send_buf,sizeof(send_buf),(struct sockaddr*)&wchy,wchyilen);printf(%sn,recv_buf+2);break;case 6:if(recv_buf1=0)printf(单聊对象不存在n);wchy.sin_family=af_inet;wchy.sin_port=htons(5053);wchy.sin_addr.s_addr=inet_addr(127.0.0.1);wchyssocket=socket(af_inet,sock_dgram,0);if(wchyssocket=invalid_socket)printf(socket()failed:%dn,wsagetlasterror();return;wchyilen=sizeof(wchy);strcpy(send_buf,);mysendmessage(wchyssocket,send_buf,sizeof(send_buf),(struct sockaddr*)&wchy,wchyilen);else if(recv_buf1=1)printf(单聊对象未在线n);wchy.sin_family=af_inet;wchy.sin_port=htons(5053);wchy.sin_addr.s_addr=inet_addr(127.0.0.1);wchyssocket=socket(af_inet,sock_dgram,0);if(wchyssocket=invalid_socket)printf(socket()failed:%dn,wsagetlasterror();return;wchyilen=sizeof(wchy);strcpy(send_buf,&);mysendmessage(wchyssocket,send_buf,sizeof(send_buf),(struct sockaddr*)&wchy,wchyilen);break;closesocket(ssocket);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.:%dn,wsagetlasterror();else if(isend=0) ;else/printf(sendto() succeeded !n);/printf(-n);3.1客户端代码#include #include #include #pragma comment(lib, ws2_32.lib)#define buffer_size 1024void 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_buf1000;char recv_bufbuffer_size;if (wsastartup(makeword(2, 2), &wsadata) != 0)printf(wsastartup()n);return 0;printf(手动连接模式中.n);char szserver256;/连接的服务器地址,ip地址printf(请输入即将连接的服务器ip地址:);gets(szserver);ser.sin_family = af_inet;ser.sin_port = htons(5050);ser.sin_addr.s_addr = inet_addr(szserver);char user20,password20;char str100,str1100,wchystr100;bool haslogin=false;/只能绑定一次,开始放在了循环里,555wchysclient=socket(af_inet,sock_dgram,0);if(wchysclient=invalid_socket)printf(socket()faild:%dn,wsagetlasterror();return 0;cli.sin_family=af_inet;cli.sin_port=htons(5053);cli.sin_addr.s_addr=htonl(inaddr_any);if(bind(wchysclient,(lpsockaddr)&cli,sizeof(cli)=socket_error)printf(bind()faild:%dn,wsagetlasterror();return 0;wchyilen=sizeof(cli);memset(recv_buf,0,sizeof(recv_buf);sclient = socket(af_inet, sock_stream, 0);if (sclient = invalid_socket)printf(socket()n);return 0;if (connect(sclient, (sockaddr*)&ser, sizeof(ser) = invalid_socket)printf(socket()n);return 0;elsebool haslogin=false;while(!haslogin)printf(-n);printf(0.注册n);printf(1.登陆n);printf(2.退出n);printf(请输入相应的数字:n);scanf(%s,&str);switch(str0)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);break;case 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);irecv=recvfrom(wchysclient,recv_buf,buffer_size,0,(sockaddr*)&cli,&wchyilen);if(irecv=socket_error)printf(recvfrom()faild:%dn,wsagetlasterror();return 0;else if(irecv=0) break;else / 接收到了正确数据printf(recv:%sn,recv_buf);if(recv_buf0=&recv_buf1=)haslogin=0;system(cls);printf(登录失败!请重新登录或注册后登录_n);if(recv_buf0=*&recv_buf1=*)haslogin=0;system(cls);printf(已经在其他地方登陆n);printf(登录失败!请重新选择用户登录或注册后登录_n);if(recv_buf0=#&recv_buf1=#)haslogin=1;system(cls);printf(登录成功_n);bool wchyhaslogin=false;while(!wchyhaslogin)printf(-n);printf(0.群聊n);printf(1.单聊n);printf(2.在线用户n);printf(3.退出n);printf(请输入相应的数字:n);scanf(%s,&wchystr);switch(wchystr0)case 0:wchyhaslogin=1;printf(输入exit退出。n);printf(-n);while(wchyhaslogin)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);elsesystem(cls);wchyhaslogin=0;break;case 1:wchyhaslogin=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.);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:%dn,wsagetlasterror();return 0;else if(irecv=0) break;else / 接收到了正确数据/printf(recv:%sn,recv_buf);if(recv_buf0=&recv_buf1=)wchyhaslogin=0;system(cls);printf(单聊对象不存在,退出了单聊模式n);if(recv_buf0=&recv_buf1=&)wchyhaslogin=0;system(cls);printf(单聊对象未在线,退出了单聊模式n);if(recv_buf0=%&recv_buf1=%)printf(输入exit退出。n);printf(-n);while(wchyhaslogin)printf();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);mysendmessage(sclient, send_buf, sizeof(send_buf);elsesystem(cls);wchyhaslogin=0;break;case 2:strcpy(send_buf,4);strcat(send_buf,user);strcat(send_buf,);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_buf);haslogin=0;wchyhaslogin=1;system(cls);break;default:system(cls);printf(请输入正确信息n);break;break;case 2:exit(0);break;default:system(cls);printf(请输入正确信息);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.:%dn,wsagetlasterror();else if(isend=0) ;else/printf(send() succeeded !n);printf(-n);3、 服务器端程序1、功能:1.1接收客户机发来的注册信息,给客户注册。其中注册的信息记录在当前文件夹下的config.txt中,注册时,检查用户名是否已存在。如果注册信息合格,那么将用户名和密码记录在文件中。向客户机发送注册结果。1.2接收客户机发来的登陆信息。获取用户名和密码,在文件中查找用户名和密码是否合法。如果合法,开始聊天。否则,返回错误信息。用户登陆成功后,选择群聊或单聊进行聊天,选择在线用户可进行查询当前在线用户,选择退出可退出登录。1.3接收客户机发来的聊天信息。将聊天信息转发给所有在线的ip。其中聊天信息有两类:a)单聊:客户机指定在线用户中的一个用户名,与其进行聊天。b)群聊:客户机向所有在线的用户发送消息。1.4面向连接的客户/服务器程序工作模型:2、原理:服务器使用事件对象i/o模式,监听套接口开启监听,创建事件,注册接收连接事件和关闭套接口事件。发生接收连接事件后,创建新事件,注册读事件和关闭套接口事件,保存响应的套接字,客户机的ip,是否登陆等必要信息。3、程序清单:3.1头文件/deal.hint finduser(userdata *data,int num,char *name)int i;for(i=0;iusername)=0) return i;return -1;void deal(char *str,userdata *data,int &num,char *response,char *ip)char userusernamelen;char passpasswordlen;/第一位字符是功能号 / 0 注册/ 1 登陆/ 2 会话/ 3 退出int i,t;if(str0=0)/注册的消息格式为 0+name+passwordfor(i=1;iusername,user);strcpy(datanum-password,pass);datanum-log=0;memset(datanum-ip,0,sizeof(datanum-ip);printf(%s 用户注册成功n,user);/-注册完成/返回成功信息strcpy(response,00);/第一位是功能号 第二位是状态号 0表示成功 1表示失败savedata(data,num);else/failprintf(%s 用户注册失败n,user);/-注册失败strcpy(response,01);else if(str0=1)/登陆的消息格式为 1+name+passwordfor(i=1;ipassword);if(strcmp(pass,datat-password)=0 & datat-log=0)/密码验证成功printf(%s 登陆成功n,user);datat-log=1;strcpy(datat-ip,ip);strcpy(response,10);else if(strcmp(pass,datat-password)=0 & datat-log=1)printf(%s 已经在其他地方登陆n,user);strcpy(response,1);elseprintf(%s 登陆密码错误n,user);strcpy(response,11);elseprintf(%s 用户不存在,登陆失败n,user);strcpy(response,12);else if(str0=2)/会话的消息格式为 2+name+(message)for(i=1;iusername,user)=0 & strcmp(datat-ip,ip)=0)/表示确实是正确用户发来的会话strcpy(response,20);strcat(response,user);strcat(response,:);strcat(response,str+i+1);printf(%s:%sn,user,str+i+1);elsestrcpy(response,21);printf(非正确用户发来会话,不予处理!n);else if(str0=

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论