各种网站制作,陕西建设厅证件查询网站,wordpress栏目修改,保定定兴网站建设一、实验名称动手打造自己的 IM二、实验目的1本次实验旨在锻炼大家的Socket编程能力#xff0c;以日常生活中广泛使用的IM软件为背景#xff0c;培养大家对于网络编程的兴趣。2、通过本次实验#xff0c;培养linux环境下网络编程能力#xff0c;使得我们对网络应用层的网络…一、实验名称动手打造自己的 IM二、实验目的1本次实验旨在锻炼大家的Socket编程能力以日常生活中广泛使用的IM软件为背景培养大家对于网络编程的兴趣。2、通过本次实验培养linux环境下网络编程能力使得我们对网络应用层的网络应用软件有了一个深入的理解这对网络课程的学习起到了很好的实践作用。三、实验内容及步骤实验内容本作业要求同学们完成一个简陋的IM的客户端和服务器端实现一些最基本和最常用的IM功能客户端功能1、4个以!开头命令!login登录命令!list列出在线用户命令!file传输文件命令!logoff注销命令。2、回显功能当其他用户登录或者登出时客户端会收到服务器的提示信息当向另一个客户端发送文件之后也会收到该客户端的提示信息。3、聊天功能两个客户端可以进行聊天以[username]: 开头的行为其他用户向你发送的聊天信息。以[username]: 开头的行为你向其他用户发送的聊天信息。服务器功能Server端基本架构多进程并发服务器实现为每个在线用户分配一个进程用以和在线用户保持通信并在子进程退出(某用户下线)时回收子进程资源。ü服务器端固定端口8081ü用户登录成功反馈提示信息ü维护在线用户信息包括IP地址和端口号用户名字用户密码等ü向在线用户发出其他用户上/下线提示信息实验步骤1、熟悉Linux下C语言的编程环境和编译方法学会用gedit来编写并修改代码及命令行工具。2、学习有关socket方面的有关知识尝试着去编写服务器端和客户端的实现连接的代码最重要的是学会使用socket()、listen()、bind()、connect()、accept()等函数的使用方法在此基础上实现客户端和服务器端的连接。3、在实现客户端和服务器端连接的基础上编写处理!login、!logoff、!list等简单的命令(无需客户端与客户端交互)这个过程最重要的是学会send()、recv()函数的使用传递套接字时要注意接收和发送的对应。4、在实现了单个客户端与服务器的用简单命令交互的基础上学习线程的有关知识在服务器端创建多线程实现服务器可以和多个客户端交互的功能。此过程最重要的是学会线程创建和使用最重要的是pthread_create(4个参数)的使用其中关键的地方是线程函数的建立及其参数的传递参数是socket这样才能在线程中实现与客户端的交互。5、在实现了多个客户端与服务器进行交互的基础上就有可能实现客户端与客户端的交互编程时一个很关键的地方就是所使用的数据结构没有一个存储logined客户端的数据结构就很难实现客户端与客户端的交互。因此需要建立一个结构体来存储客户端的socket、port(可选)、username、flag(状态)。两种方案1)从服务器获得另一个客户端的端口号和IP后让客户端与客户端建立连接实现直接交互这就是P2P结构编程时我试着使用了这种方法但是连接总是出问题。2)通过服务器实现客户端之间的交互简单来说就是客户端把信息通过socket发送到服务器服务器再把信息通过不同的socket发送到客户端这是建立在每个客户端都有自己的socket的基础上的。我选择了第二种方案来实现客户端的交互。6、编程进行到这里我突然意识到了如果客户端没有监听服务器的代码无法接收和识别服务器的信息是客户端要发送的信息、还是服务其本身要发送的信息思考良久无奈之下只能大篇幅的修改代码在客户端使用双线程一个用于监听键盘的输入一个用于监听服务器是否发送信息这样当键盘输入时一个线程接收并负责向服务器发送信息当收到服务器发送的信息时另一个线程接收并把信息输出到终端上。7、在以上的基础上就可以实现客户端的通话及文件的发送最后就是调试程序并整理输出的格式。四、实验分析1server.c编译及运行结果图1处于监听状态的服务器2开启另外终端运行客户端程序第一个用户Me运行客户端程序之后使用命令!login登录成功登录后会收到服务器的发送的信息结果如下图2 一个client登陆成功后的服务器图3第一个客户端Me登陆成功另起两个终端第二个客户端You和第三个客户端Him登录后结果如下图4多个客户端登陆后的服务器3指令!list的使用图5 Me客户端上执行!list命令4!logoff命令当用户Me执行!logoff后客户端显示服务器发送的信息此时使用!list指令结果如下图6客户端Him执行!logoff命令图7客户端Him执行!logoff命令后Me执行!list的结果5聊天功能演示图8 Me客户端和You客户端进行通话图9You客户端和Me客户端通话6指令!file的使用文件传输功能演示图10You客户端向Me发送lilufeng.pdf文件显示成功图11 Me客户端接收文件成功信息7、几种错误处理结果如下图12用户名错误登录失败图13发送文件时用户不在线、发送失败图14Me想和You对话You没有登录连接失败五、实验结论难点1、本实验是基于Linux环境下使用C语言编写而成这两者都需要实验前进行深入的探索和学习对我而言加大了编程和实现的难度。2、对socket和thread方面的知识可以说一无所知编程的过程中要不断地学习才能向前迈一小步。感受1、这次实验的过程中我深知自己的知识的匮乏实验的过程可以说完全是一个探索的过程对用到的函数我必须要在Dev等工具下先进性一定的应用和学习才能真正掌握其用法和内涵实践的过程中学到了很多的知识而且在编程的后面阶段感觉对这些知识已经能够熟练地应用最有说服力的就是那些函数的掌握可见软件这个行业只有在实践中才能真正的学到本领。2、编程的前后我的代码被改了很多遍因为开始编程的时候没有一个整体的构思只能走一步算一步每走一步都是那么的艰难线程的加入和数据结构的改变都使原来的代码结构发生天翻地覆的变化到最后在客户端加入双线程时整体的代码又改了一遍所以说这次试验让我感觉非常的累而且过程中感觉网络编程是那么的复杂现在想想这些东西还是很简单的。由此我明白了开发软件前为什么要进行详细的设计看着是浪费时间其实那是在节省时间和精力而且是开发出一个软件的基础。3、通过这次试验让我学会了关于网络的socket和P2P等很多知识这些知识在短期或者说今生难于忘记当然还有操作系统方面的thread和process方面的知识。4、同时我也感受到了IT人士的辛劳其实我一直都在感受到只不过这次更加强烈罢了不过辛劳后看到自己的成果和感到内心的充实觉得付出还是值得的。客户端程序源码//[浠爜]tcpclient.c#include#include#include#include#include#include#include#include#include#defineSERVER_PORT 8081 //define the defualt connect portid#defineBUFFER_SIZE 255 //buf sizeintclifd,length 0;//socket sizecharbuf[BUFFER_SIZE]; //the buffer of socketpthread_tthread;//thread discriptioncharcommand[100],uName[20],pwd[20];void*listenServer(int);//listen and receive message from the serverintcli_socket_connect_server(int);//create socket and connect theserverintmain(int argc){clifd cli_socket_connect_server(SERVER_PORT);//return the socketwhile(1){ charfrontcmd[20],ch1,ch2;int countcmd0,countFcmd0;memset(frontcmd, ,sizeof(frontcmd));memset(command, ,sizeof(command));memset(buf, ,sizeof(buf));while(ch1 getchar()) //input the command{if(ch1 ){while(ch2 getchar()){if(ch2 n)break;elsecommand[countcmd] ch2;}break;}else if(ch1 n)break;elsefrontcmd[countFcmd] ch1;}//inputover:frontcmd is the really commandif(frontcmd[0] )//talk function process{strcpy(buf,);send(clifd,buf,BUFFER_SIZE,0);char *talkto;talkto strtok(frontcmd,:);strcpy(buf,talkto);//talk to whomstrcat(buf,:);//:is used to strtok in the serverstrcat(buf,command);//what you sendsend(clifd,buf,BUFFER_SIZE,0);}if(strcmp(frontcmd,!logoff) 0)//logoff command process{strcpy(buf,!logoff);send(clifd,buf,BUFFER_SIZE, 0);strcpy(buf,uName);send(clifd,buf,BUFFER_SIZE, 0 );close(clifd);pthread_exit(NULL);break;}//end of logoffifif(strcmp(frontcmd,!list) 0)//list command process{strcpy(buf,!list);send(clifd,buf,BUFFER_SIZE, 0 );}//end of listifif(strcmp(frontcmd,!login) 0)//login command process{strcpy(buf,!login);send(clifd,buf,BUFFER_SIZE, 0 );printf(Username:t);scanf(%s,uName);printf(Password:t);scanf(%s,pwd);strcpy(buf,uName);send(clifd,buf,BUFFER_SIZE, 0 );length recv(clifd,buf,BUFFER_SIZE,0);if(length 0){printf( error comeswhen recieve data from server! send filen);exit( 1 );}printf(Fromserver:nt%sn,buf);if(pthread_create(thread, NULL, (void*)listenServer, (void *)clifd) 0) //after login success createthe listenServer thread{printf(listenthread create success!n);}else{printf(listenthread create failed!n);exit(1);}}//end of loginifif(strcmp(frontcmd,!file) 0){strcpy(buf,frontcmd);//send front command(!file) to the serversend(clifd,buf,BUFFER_SIZE,0);char*file,*toUser;file strtok(command, );//filetoUser strtok(NULL, );//destination userprintf(filename:t%sntoUser:t%s,file,toUser);strcpy(buf,toUser);//send the file to whomsend(clifd,buf,BUFFER_SIZE,0);}//end of fileif}//end of whilereturn 0;}void*listenServer(int file_socket){while(recv(file_socket,buf,BUFFER_SIZE,0)0){char *flagcmd NULL,*printInfo NULL;flagcmd strtok(buf,|);printInfo strtok(NULL,|);if(strcmp(flagcmd,!list) 0)//list the user that loginednowprintf(fromserver:n%s,printInfo);elseif(strcmp(flagcmd,!logoff) 0)//logoffprintf(fromserver:nt%s,printInfo);elseif(strcmp(flagcmd,!file) 0)//send the file{if(strcmp(printInfo,0) 0)//destination user does not loginprintf(Fromserver:ntuser does not login,file failed!n);else//destination user loginedprintf(nConnectsuccess!file success!n);}elseif(strcmp(flagcmd,!msg) 0)//receive the file message{printf(Fromsever:nt%s,printInfo);}elseif(strcmp(flagcmd,!talk) 0)//talk message{if(strcmp(printInfo,0) 0)printf(The userdoes not login!n);elseprintf(%sn,printInfo);}elseprintf(Pleasedebug!);}}intcli_socket_connect_server(int serverPort){structsockaddr_in cliaddr;socklen_t socklen sizeof(cliaddr);charsever[20];//store the IPintclient_socket;if((client_socket socket(AF_INET,SOCK_STREAM, 0)) 0)//create socket of the client{printf( createsocket error!n );exit( 1 );}bzero( cliaddr,sizeof(cliaddr));cliaddr.sin_family AF_INET;inet_aton(sever, cliaddr.sin_addr);cliaddr.sin_port htons(serverPort);//port ofthe severcliaddr.sin_addr.s_addr htons(INADDR_ANY);//the same IP with thesever.Connect auto!if(connect(client_socket,(struct sockaddr * ) cliaddr, socklen) 0 )//connectthe server{printf( cantconnect!n );exit( 1 );}returnclient_socket; //return the socket}服务器端源码//tcpserver.c#include#include#include#include#include#include#include#include#include#defineSERVER_PORT 8081 //define the defualt connect portid#defineLENGTH_OF_LISTEN_QUEUE 10 //length of listen queue in server#defineMAX_THREAD 10#defineBUFFER_SIZE 255#defineSUCCESS_MESSAGE LoginSuccess!#defineFAIL_MESSAGE Login Failed!#defineTOTAL_USER_NUM 6structclientInformation{int flag;//recordthe struct state: 0 is emptychar loginUsr[20];//the users that have loginedint socket;//store the logined usessocket};structclientInformation clientInfo[TOTAL_USER_NUM];//logined usersarrayintservfd,sever_socket; //the socketint len0;//record the length of the socketint numOfThread 0;//record the number ofthreadschar users[6][10] {Me,You,Him,Her,user,tmd};//users that can logincharbuf[BUFFER_SIZE]; //the capacity of thesocketpthread_tthread[MAX_THREAD]; //thread discriptionstructsockaddr_in servaddr,cliaddr;void*docommand(int);//thread functionint main(intargc){int num;for(num 0; num TOTAL_USER_NUM; num){clientInfo[num].flag 0;clientInfo[num].socket 0;}if ((servfd socket(AF_INET,SOCK_STREAM, 0 )) 0 )//createsocket in the server{printf( create socketerror!n );exit( 1);}bzero( servaddr,sizeof(servaddr));servaddr.sin_family AF_INET;servaddr.sin_port htons(SERVER_PORT);servaddr.sin_addr.s_addr htons(INADDR_ANY);if(bind(servfd,(struct sockaddr* ) servaddr,sizeof(servaddr)) 0)//bind{printf( bind toport %d failure!n ,SERVER_PORT);exit( 1);}if(listen(servfd,LENGTH_OF_LISTEN_QUEUE) 0)//listen{printf(call listen failure!n );exit( 1);}while(numOfThread MAX_THREAD){socklen_t length sizeof(cliaddr);sever_socket accept(servfd,(struct sockaddr* ) cliaddr, length);//acceptthe loginif(sever_socket 0 ){printf(error comes when call accept!n );break;}else{//void* arg[] {sever_socket};if(pthread_create(thread[numOfThread], NULL,(void *)docommand, (void *)sever_socket) ! 0)printf(绾跨▼%d鍒涘缓澶辫触!n,numOfThread); //createthe new thread to the login clientelseprintf(绾跨▼%d琚垱寤簄,numOfThread);}}close(servfd);return 0;}void *docommand(intsever_socket){while( 1 ){// server loop will nerver exit unless any body kill the processmemset(buf, ,sizeof(buf));len recv(sever_socket, buf,BUFFER_SIZE, 0); //recv thecommandif(len 0){printf( error comes whenrecieve data from client ! );exit( 1 );}else{if(strcmp(buf,) 0) //talkprocess{len recv(sever_socket, buf,BUFFER_SIZE, 0);//recv the user name that the file will be senttoif(len 0){printf(error comes whenrecieve data from client ! );exit( 1 );}chartemp[100],*talkto;strcpy(temp,buf);//temp store what will be senttalkto strtok(buf,:);int j;for(j 0;j TOTAL_USER_NUM;j){if(clientInfo[j].flag 1){if(strcmp(clientInfo[j].loginUsr,talkto) 0){strcpy(buf,!talk|);strcat(buf,temp);//move temp(the information) to bufsend(clientInfo[j].socket,buf,BUFFER_SIZE,0);//send the talkingmessage to whom what you talkbreak;}}}if(j TOTAL_USER_NUM){strcpy(buf,!talk);strcat(buf,|0);//0 user does not loginsend(sever_socket,buf,BUFFER_SIZE, 0 ); //send message(user doesnot login)}}elseif(strcmp(buf,!file) 0) //file process{len recv(sever_socket, buf,BUFFER_SIZE, 0);//recv the user name that the file will be senttoif(len 0){printf(error comes whenrecieve data from client ! );exit( 1 );}int i;for(i 0;i TOTAL_USER_NUM;i){if(clientInfo[i].flag 1){if(strcmp(clientInfo[i].loginUsr,buf) 0){strcpy(buf,!file|);strcat(buf,1);//1 user loginedsend(sever_socket,buf,BUFFER_SIZE, 0 ); //send to the client whosend file(receiver)strcpy(buf,!msg|nreceived the file!n);send(clientInfo[i].socket,buf,BUFFER_SIZE,0);//tell the client torecv the filebreak;}}}if(i TOTAL_USER_NUM){strcpy(buf,!file);strcat(buf,|0);//0 user does not loginsend(sever_socket,buf,BUFFER_SIZE, 0 ); //send message(user doesnot login)}}//end of ifelseif(strcmp(buf,!list) 0) //list the logined users process{strcat(buf,|);int k;for(k 0; k TOTAL_USER_NUM; k){if(clientInfo[k].flag 1){strcat(buf,clientInfo[k].loginUsr);strcat(buf,n);}}send(sever_socket,buf,BUFFER_SIZE,0); //send all logined users toclient}//end of else if1elseif(strcmp(buf,!logoff) 0) // logoff process{while(1){strcat(buf,|logoffsuccess!n);send(sever_socket,buf,BUFFER_SIZE,0); //send logoff successmessagememset(buf, ,sizeof(buf));len recv(sever_socket, buf,BUFFER_SIZE, 0); //recv the login users nameint k;for(k 0; k TOTAL_USER_NUM; k)//move it out from theclientinformation struct{if(strcmp(buf,clientInfo[k].loginUsr) 0){strcpy(clientInfo[k].loginUsr, );clientInfo[k].flag 0;clientInfo[k].socket 0;break;}}close(sever_socket);numOfThread--;pthread_exit(NULL);break;}}//end of else if2elseif(strcmp(buf,!login) 0)//login process{len recv(sever_socket, buf,BUFFER_SIZE, 0); //recv the login users nameif(len 0){printf(error comes whenrecieve data from client ! login );exit( 1 );}printf(fromclient:%stIP:%stPort:%dn ,buf,inet_ntoa(cliaddr.sin_addr),ntohs(cliaddr.sin_port));int i;for(i 0;i TOTAL_USER_NUM;i)//judge whether have thisuser{if(strcmp(buf,users[i]) 0){for(i 0;i TOTAL_USER_NUM;i){if(clientInfo[i].flag 0){strcpy(clientInfo[i].loginUsr,buf);clientInfo[i].socket sever_socket;clientInfo[i].flag 1;break;}}strcpy(buf,SUCCESS_MESSAGE);send(sever_socket,buf,BUFFER_SIZE, 0 ); //send login successmessagebreak;}}if(i TOTAL_USER_NUM){printf(No usercalled %s! Login failed!n,buf);memset(buf, ,sizeof(buf));strcpy(buf,FAIL_MESSAGE);send(sever_socket,buf,BUFFER_SIZE, 0 ); //send login failedmessage}}//end of else if3} //end of else}// end of while}又不懂得地方欢迎留言询问我必尽力解答