socket网络课程设计报告文档格式.docx
《socket网络课程设计报告文档格式.docx》由会员分享,可在线阅读,更多相关《socket网络课程设计报告文档格式.docx(15页珍藏版)》请在冰豆网上搜索。
4、调试并修改程序,使之实现设计要求
5、测试程序,从中找出程序缺陷和可改进内容
6、重复修改和测试,以达到自己理想的功能
7、程序评定测试
8、撰写设计报告
四、设计过程
第一个版本并未实现收发同步,只是简单的阻塞式通信。
因为没有用到多线程,所以在程序监听网络数据写入时不能监听键盘输入,所以只能发一条后接一条,其中的问题可想而知。
第二个版本用多线程实现了同时收发问题,在连接建立后新建一个线程用来等待键盘输入,而主体线程等待网络输入,当网络输入错误时(连接断开),结束线程并作下一步处理。
这个版本就上个版本改进很多,主要可以即时在屏幕输出接收到的消息,同时也出现了另外一个缺陷:
当键盘输入到一半时程序收到了网络的信息,这个时候程序的做法是直接输出这条信息,这导致我们键盘输入的信息被切断,很不人性化。
第三个版本,也就是目前评测的版本,这个版本利用临界值来锁定屏幕资源,让程序在同一时刻只能一个程序拥有屏幕控制权,这样保证了不会交叉显示。
另外我用自己的输入输出代替了原有的scanf和printf,这样使读写更安全可靠。
同时改进的还有等待机制,在服务器启动之后立即监听本机6000端口,建立连接之后直接开辟线程等待输入。
而客户端启动时要输入目的机的ip地址,连接完成时打印欢迎信息并开始进入聊天。
聊天结束(断开)之后可以重新输入目的机器ip地址以建立新连接。
五、调用顺序图
服务端
Socket
Blind
Accept
Recv
Send
Close
Print
Listen
客户端
Connect
六、源代码
1、共有文件soc.h(调试用文件)
#include<
time.h>
voidgetime(char*s_tim){
time_trawtime;
structtm*timeinfo;
time(&
rawtime);
timeinfo=localtime(&
sprintf(s_tim,"
%02d:
%02d"
timeinfo->
tm_hour,timeinfo->
tm_min,timeinfo->
tm_sec);
return;
}
2、服务端server.cpp
stdio.h>
Winsock2.h>
windows.h>
conio.h>
#include"
socs.h"
#pragmacomment(lib,"
ws2_32.lib"
)
DWORDWINAPIgotsListen(LPVOID);
DWORDWINAPIsetsListen(LPVOID);
voidgeta(char*s);
voidputa(char*,int);
voidgetime(char*);
CRITICAL_SECTIONg_cs;
CRITICAL_SECTIONt_cs;
charbufer[1000];
intbuflen;
boollinked;
voidmain(void){
HANDLEgotHandle;
HANDLEsetHandle;
WORDwVerR;
WSADATAwsD;
wVerR=MAKEWORD(1,1);
if(WSAStartup(wVerR,&
wsD))
return;
if(LOBYTE(wsD.wVersion)!
=1||HIBYTE(wsD.wVersion)!
=1){
WSACleanup();
}
SOCKETscSr=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_INadrSr;
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_INadrCl;
intlen=sizeof(SOCKADDR);
while(true){
printf("
bind[%d]success!
\n"
6000);
SOCKETscCon=accept(scSr,(SOCKADDR*)&
adrCl,&
len);
chars_adr[100];
strcpy(s_adr,inet_ntoa(adrCl.sin_addr));
linked=true;
link[%s]becreated!
s_adr);
InitializeCriticalSection(&
t_cs);
gotHandle=CreateThread(NULL,0,&
gotsListen,&
scCon,0,NULL);
setHandle=CreateThread(NULL,0,&
setsListen,&
while(linked){
Sleep(10);
}
TerminateThread(setHandle,NULL);
CloseHandle(gotHandle);
CloseHandle(setHandle);
DeleteCriticalSection(&
closesocket(scCon);
\nlink[%s]closed!
closesocket(scSr);
DWORDWINAPIgotsListen(LPVOIDlpParam)
{
chargots[1000];
while(linked)
{
//EnterCriticalSection(&
g_cs);
if(recv(*(SOCKET*)lpParam,gots,1000,0)==-1)break;
//LeaveCriticalSection(&
puta(gots,1);
linked=false;
return0;
DWORDWINAPIsetsListen(LPVOIDlpParam){
while(linked){
geta(bufer);
send(*(SOCKET*)lpParam,bufer,strlen(bufer)+1,0);
puta(bufer,0);
ExitThread(NULL);
voidputa(char*s,intsta){
inti=1;
chars_tim[16];
getime(s_tim);
switch(sta){
case0:
EnterCriticalSection(&
while(i--)
printf("
\b\b"
);
[local]%s\n%s\n"
s_tim,s);
LeaveCriticalSection(&
break;
case1:
i+=buflen;
[NET]%s\n%s\n"
>
%s"
bufer);
};
voidgeta(char*s){
charc;
EnterCriticalSection(&
printf("
"
bufer[buflen=0]='
\0'
;
LeaveCriticalSection(&
while(c=getch()){
if(c>
31&
&
c<
127){
EnterCriticalSection(&
s[buflen++]=c;
s[buflen]='
%c"
c);
LeaveCriticalSection(&
}else{
switch(c){
case13:
EnterCriticalSection(&
while(buflen--)
printf("
LeaveCriticalSection(&
return;
case8:
if(buflen){
buflen--;
s[buflen]='
}
break;
}
3、客户端client.cpp
voidgeta(char*);
chars_adr[10];
if(WSAStartup(MAKEWORD(1,1),&
if(wsD.wVersion!
=MAKEWORD(1,1)){
return;
ReadytoConnect:
scanf("
SOCKADDR_INadrSr;
adrSr.sin_addr.S_un.S_addr=inet_addr(s_adr);
adrSr.sin_family=AF_INET;
adrSr.sin_port=htons(6000);
linked=!
connect(scSr,(SOCKADDR*)&
if(linked){
link[%s]createdsuccess!
InitializeCriticalSection(&
gotHandle=CreateThread(NULL,0,&
scSr,0,NULL);
setHandle=CreateThread(NULL,0,&
while(linked){
Sleep(10);
TerminateThread(setHandle,NULL);
TerminateThread(gotHandle,NULL);
CloseHandle(gotHandle);
CloseHandle(setHandle);
DeleteCriticalSection(&
Failedtoconnect%s,checkitandtryagain!
closesocket(scSr);
\nlink[%s]beclosed!
{
chargots[10000];
//puts("
running"
inti=2;
七、调试运行
本实例在同一ip和不同分别做了测试,运行状况达到了预期的效果,下面是相关的几张运行截图:
服务器以及客户端启动的画面
建立连接之后提示信息以及命令提示符
客户端向服务器发送信息
下面来做一系列的测试查看程序防交叉输出的功能:
1、连接之后服务端在写一些内容
2、客户端发送了一条消息,服务端将消息插入,并继续等待输入端输入
3、服务器继续编辑文本并发送(注意服务器在收到消息之后可以修改输入的内容)
断开连接
八、心得体会
经过了两个星期的学习,这次课程设计基本圆满完成了,这次课程设计我收获了很多。
在以前的程序设计中我从没有用到过网络连接,这使我的代码在功能方面的限制非常严重,我曾尝试着用其他的方式来实现网络功能,但是多少都有些缺陷。
写完了这个课程设计之后我对程序设计的兴趣更加浓烈了,我感觉我能用它来实现的功能也扩大了很多。
这次课程设计给我带来了很多经验,我以前单纯的以为网络编程就是用几个api就可以完成,真正操作起来会发现网络编程的这种特性会带来很多单机程序不可能遇到的问题,让我明白了只有真正的动手实践才是了解技术和学习技术的最佳途径。
这次课程设计中老师的耐心指导给我很大的帮助,刚接触网络编程遇到了各种错误和问题,老师都一一帮我指出并解决了。
感觉我现在还很不足,还要加倍努力才能实现我的程序梦想。
另外老师也给我提出了很切合实际的几点要求,让我有更明确的学习目标,也有了更多的学习动力。