《socket网络课程设计报告(共14页).doc》由会员分享,可在线阅读,更多相关《socket网络课程设计报告(共14页).doc(14页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精选优质文档-倾情为你奉上计算机网络课程设计报告网络连天程序的设计与实现姓 名: 李坚 学 号: 班 级: 计算机002 指导老师: 文宏 湖南科技大学计算机科学与工程学院2011年9月一、 课程设计题目利用Windows Socket编程实现局域网的聊天程序,要求能实现消息的发送和接收,以及聊天软件的细节问题。二、 题目分析拿到题目之后先来了解windows socket连接的过程与相关的API函数。按照题目的要求,我简单的分析了下并做了初步的设计:利用tcp协议建立连接,这样服务器和客户端分离,服务端先启动并监听端口,客户端启动之后连接服务端建立连接,接着收发聊天信息。当任意一方连接断开的
2、时候给出适当的提示并结束程序。因为功能比较简单,所以设计起来还是比较容易的。实际的操作中我遇到了很多新奇的问题并通过一些方案修改或者实现了最终的功能。三、 设计步骤1、 熟悉网络编程概念以及一些基本知识2、 在windows 的编程环境下熟悉了常用socket函数3、 先整体再局部顺序设计程序4、 调试并修改程序,使之实现设计要求5、 测试程序,从中找出程序缺陷和可改进内容6、 重复修改和测试,以达到自己理想的功能7、 程序评定测试8、 撰写设计报告四、 设计过程第一个版本并未实现收发同步,只是简单的阻塞式通信。因为没有用到多线程,所以在程序监听网络数据写入时不能监听键盘输入,所以只能发一条后
3、接一条,其中的问题可想而知。第二个版本用多线程实现了同时收发问题,在连接建立后新建一个线程用来等待键盘输入,而主体线程等待网络输入,当网络输入错误时(连接断开),结束线程并作下一步处理。这个版本就上个版本改进很多,主要可以即时在屏幕输出接收到的消息,同时也出现了另外一个缺陷:当键盘输入到一半时程序收到了网络的信息,这个时候程序的做法是直接输出这条信息,这导致我们键盘输入的信息被切断,很不人性化。第三个版本,也就是目前评测的版本,这个版本利用临界值来锁定屏幕资源,让程序在同一时刻只能一个程序拥有屏幕控制权,这样保证了不会交叉显示。另外我用自己的输入输出代替了原有的scanf和printf,这样使
4、读写更安全可靠。同时改进的还有等待机制,在服务器启动之后立即监听本机6000端口,建立连接之后直接开辟线程等待输入。而客户端启动时要输入目的机的ip地址,连接完成时打印欢迎信息并开始进入聊天。聊天结束(断开)之后可以重新输入目的机器ip地址以建立新连接。五、 调用顺序图服务端SocketBlindAcceptRecvSendClosePrintListenSocket客户端ConnectRecvPrintSendClose六、 源代码1、 共有文件soc.h(调试用文件)#include void getime(char *s_tim)time_t rawtime;struct tm * ti
5、meinfo;time ( &rawtime );timeinfo = localtime (&rawtime );sprintf(s_tim,%02d:%02d:%02d,timeinfo-tm_hour,timeinfo-tm_min,timeinfo-tm_sec);return ;2、 服务端server.cpp#include #include #include #include #include socs.h#pragma comment(lib,ws2_32.lib)DWORD WINAPI gotsListen(LPVOID);DWORD WINAPI setsListen(L
6、PVOID);void geta(char *s);void puta(char*,int);void getime(char *);CRITICAL_SECTION g_cs;CRITICAL_SECTION t_cs;char bufer1000;int buflen;bool linked;void main(void)HANDLE gotHandle;HANDLE setHandle;WORD wVerR;WSADATA wsD;wVerR=MAKEWORD(1,1);if(WSAStartup(wVerR,&wsD)return ;if(LOBYTE(wsD.wVersion)!=1
7、|HIBYTE(wsD.wVersion)!=1)WSACleanup();return ;SOCKET scSr=socket(AF_INET,SOCK_STREAM,0);SOCKADDR_IN adrSr;adrSr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);adrSr.sin_family=AF_INET;adrSr.sin_port=htons(6000);bind(scSr,(SOCKADDR *)&adrSr,sizeof(SOCKADDR);listen(scSr,5);SOCKADDR_IN adrCl;int len=sizeof(SOC
8、KADDR);while(true)printf(bind%d success!n,6000);SOCKET scCon=accept(scSr,(SOCKADDR *)&adrCl,&len);char s_adr100;strcpy(s_adr,inet_ntoa(adrCl.sin_addr);linked=true;printf(link%s be created!n,s_adr);InitializeCriticalSection(&t_cs);gotHandle=CreateThread(NULL,0,&gotsListen,&scCon,0,NULL);setHandle=Cre
9、ateThread(NULL,0,&setsListen,&scCon,0,NULL);while(linked)Sleep(10);TerminateThread(setHandle,NULL);CloseHandle(gotHandle);CloseHandle(setHandle);DeleteCriticalSection(&t_cs);closesocket(scCon);printf(nlink%s closed!n,s_adr);closesocket(scSr);return ;DWORD WINAPI gotsListen(LPVOID lpParam) char gots1
10、000;while(linked)/EnterCriticalSection(&g_cs);if(recv(*(SOCKET *)lpParam,gots,1000,0)=-1)break;/LeaveCriticalSection(&g_cs);puta(gots,1);linked=false; return 0; DWORD WINAPI setsListen(LPVOID lpParam)while(linked)geta(bufer);/EnterCriticalSection(&g_cs);send(*(SOCKET *)lpParam,bufer,strlen(bufer)+1,
11、0);/LeaveCriticalSection(&g_cs);puta(bufer,0);ExitThread(NULL);return 0;void puta(char *s,int sta)int i=1;char s_tim16;getime(s_tim);switch(sta)case 0:EnterCriticalSection(&t_cs);while(i-)printf(b b);printf(local %sn %sn,s_tim,s);LeaveCriticalSection(&t_cs);break;case 1:EnterCriticalSection(&t_cs);i
12、+=buflen;while(i-)printf(b b);printf(NET %sn %sn,s_tim,s);printf(%s,bufer);LeaveCriticalSection(&t_cs);break;void geta(char *s)char c;EnterCriticalSection(&t_cs);printf();buferbuflen=0=0;LeaveCriticalSection(&t_cs);while(c=getch()if(c31&c127)EnterCriticalSection(&t_cs);sbuflen+=c;sbuflen=0;printf(%c
13、,c);LeaveCriticalSection(&t_cs);elseswitch(c)case 13:EnterCriticalSection(&t_cs);while(buflen-)printf(b b);LeaveCriticalSection(&t_cs);return;case 8:EnterCriticalSection(&t_cs);if(buflen)buflen-;printf(b b);sbuflen=0;LeaveCriticalSection(&t_cs);break;3、 客户端 client.cpp#include #include #include #incl
14、ude #include socs.h#pragma comment(lib,ws2_32.lib)DWORD WINAPI gotsListen(LPVOID);DWORD WINAPI setsListen(LPVOID);void geta(char *);void puta(char*,int);void getime(char *);CRITICAL_SECTION t_cs;char bufer1000;int buflen;bool linked;void main(void)HANDLE gotHandle;HANDLE setHandle;char s_adr10;WSADA
15、TA wsD;if(WSAStartup(MAKEWORD(1,1),&wsD)return ;if(wsD.wVersion!=MAKEWORD(1,1)WSACleanup();return;SOCKET scSr=socket(AF_INET,SOCK_STREAM,0);while(true)printf(Ready to Connect:);scanf(%s,s_adr);SOCKADDR_IN adrSr;adrSr.sin_addr.S_un.S_addr=inet_addr(s_adr);adrSr.sin_family=AF_INET;adrSr.sin_port=htons
16、(6000);linked=!connect(scSr,(SOCKADDR *)&adrSr,sizeof(SOCKADDR);if(linked)printf(link%s created success!n,s_adr);InitializeCriticalSection(&t_cs);gotHandle=CreateThread(NULL,0,&gotsListen,&scSr,0,NULL);setHandle=CreateThread(NULL,0,&setsListen,&scSr,0,NULL);while(linked)Sleep(10);TerminateThread(set
17、Handle,NULL);TerminateThread(gotHandle,NULL);CloseHandle(gotHandle);CloseHandle(setHandle);DeleteCriticalSection(&t_cs);elseprintf(Failed to connect %s,check it and try again!n,s_adr);closesocket(scSr);printf(nlink%s be closed!n,s_adr);return ;DWORD WINAPI gotsListen(LPVOID lpParam) char gots10000;w
18、hile(linked)/puts(running);/EnterCriticalSection(&g_cs);if(recv(*(SOCKET *)lpParam,gots,1000,0)=-1)break;/LeaveCriticalSection(&g_cs);puta(gots,1);linked=false;ExitThread(NULL); return 0;DWORD WINAPI setsListen(LPVOID lpParam)while(linked)geta(bufer);/EnterCriticalSection(&g_cs);send(*(SOCKET *)lpPa
19、ram,bufer,strlen(bufer)+1,0);/LeaveCriticalSection(&g_cs);puta(bufer,0);ExitThread(NULL);return 0;void puta(char *s,int sta)int i=2;char s_tim16;getime(s_tim);switch(sta)case 0:EnterCriticalSection(&t_cs);while(i-)printf(b b);printf(local %sn %sn,s_tim,s);LeaveCriticalSection(&t_cs);break;case 1:Ent
20、erCriticalSection(&t_cs);i+=buflen;while(i-)printf(b b);printf(NET %sn %sn,s_tim,s);printf(%s,bufer);LeaveCriticalSection(&t_cs);break;void geta(char *s)char c;EnterCriticalSection(&t_cs);printf();buferbuflen=0=0;LeaveCriticalSection(&t_cs);while(c=getch()if(c31&c127)EnterCriticalSection(&t_cs);sbuf
21、len+=c;sbuflen=0;printf(%c,c);LeaveCriticalSection(&t_cs);elseswitch(c)case 13:EnterCriticalSection(&t_cs);while(buflen-)printf(b b);LeaveCriticalSection(&t_cs);return;case 8:EnterCriticalSection(&t_cs);if(buflen)buflen-;printf(b b);sbuflen=0;LeaveCriticalSection(&t_cs);break;七、 调试运行本实例在同一ip和不同分别做了测
22、试,运行状况达到了预期的效果,下面是相关的几张运行截图:服务器以及客户端启动的画面建立连接之后提示信息以及命令提示符客户端向服务器发送信息下面来做一系列的测试查看程序防交叉输出的功能:1、 连接之后服务端在写一些内容2、 客户端发送了一条消息,服务端将消息插入,并继续等待输入端输入3、 服务器继续编辑文本并发送(注意服务器在收到消息之后可以修改输入的内容)断开连接八、 心得体会经过了两个星期的学习,这次课程设计基本圆满完成了,这次课程设计我收获了很多。在以前的程序设计中我从没有用到过网络连接,这使我的代码在功能方面的限制非常严重,我曾尝试着用其他的方式来实现网络功能,但是多少都有些缺陷。写完了这个课程设计之后我对程序设计的兴趣更加浓烈了,我感觉我能用它来实现的功能也扩大了很多。这次课程设计给我带来了很多经验,我以前单纯的以为网络编程就是用几个api就可以完成,真正操作起来会发现网络编程的这种特性会带来很多单机程序不可能遇到的问题,让我明白了只有真正的动手实践才是了解技术和学习技术的最佳途径。这次课程设计中老师的耐心指导给我很大的帮助,刚接触网络编程遇到了各种错误和问题,老师都一一帮我指出并解决了。感觉我现在还很不足,还要加倍努力才能实现我的程序梦想。另外老师也给我提出了很切合实际的几点要求,让我有更明确的学习目标,也有了更多的学习动力。专心-专注-专业