服务器回射程序设计Word格式.docx
《服务器回射程序设计Word格式.docx》由会员分享,可在线阅读,更多相关《服务器回射程序设计Word格式.docx(17页珍藏版)》请在冰点文库上搜索。
intquit(SOCKETs);
SOCKETtcp_server(ULONGuIP,USHORTuPort);
SOCKETtcp_server(char*hname,char*sname);
SOCKETtcp_client(char*hname,char*sname);
SOCKETtcp_client(ULONGuIP,USHORTuPort);
};
intCSocketFrame:
:
start_up(void)
WORDwVersionRequested;
WSADATAwsaData;
intiResult;
wVersionRequested=MAKEWORD(2,2);
iResult=WSAStartup(wVersionRequested,&
wsaData);
if(iResult!
=0)
{
printf("
WSAStartup调用错误,错误号:
%d\n"
WSAGetLastError());
return-1;
}
/*
if(LOBYTE(wsaData.wVersion!
=2||HIBYTE(wsaData.wVersion)!
=2))
无法找到可用的WSD版本\n"
);
WSACleanup();
//告诉用户无法找到可用的WSD
}
else
WS2.2初始化成功!
\n"
}*/
return0;
}
clean_up(void)
intiResult;
iResult=WSACleanup();
if(iResult==SOCKET_ERROR)
{
//WSACleanup()调用失败
WSACleanup调用错误,错误号:
}
else
Winsocketdll释放成功!
);
return0;
set_address(char*hname,char*sname,structsockaddr_in*sap,char*protocol)
structservent*sp;
structhostent*hp;
char*endptr;
unsignedshortport;
unsignedlongulAddr=INADDR_NONE;
//将地址结构socketsddr_in初始化为0,并将地址族设为AF_INET
memset(sap,0,sizeof(*sap));
sap->
sin_family=AF_INET;
if(hname!
=NULL)
//如果hname不为空,转化地址格式
ulAddr=inet_addr(hname);
if(ulAddr==INADDR_NONE||ulAddr==INADDR_ANY)
//调用错误,调用gethostbyname获得主机地址
hp=gethostbyname(hname);
if(hp==NULL)
{
printf("
未知的主机名,错误号:
return-1;
}
sap->
sin_addr=*(structin_addr*)hp->
h_addr;
sin_addr.S_un.S_addr=ulAddr;
}
//如果调用者没有指明一个主机名或地址,则设为通配地址
sap->
sin_addr.s_addr=htonl(INADDR_ANY);
//尝试转换sname为一个整数
port=(unsignedshort)strtol(sname,&
endptr,0);
if(*endptr=='
\0'
)
//如果成功转化为网络字节序
sin_port=htons(port);
//如果失败,则假定是一个服务名称,通过getservbyname()函数获得端口号
sp=getservbyname(sname,protocol);
if(sp==NULL)
未知服务,错误号:
}
sin_port=sp->
s_port;
quit(SOCKETs)
intiResult=0;
iResult=closesocket(s);
printf("
closesocket调用错误,错误号:
iResult=clean_up();
returniResult;
SOCKETCSocketFrame:
tcp_server(char*hname,char*sname)
SOCKETListenSocket;
sockaddr_inlocal;
constinton=1;
//为服务器的本机地址设置用户输入的地址以及端口号
if(set_address(hname,sname,&
local,(char*)"
tcp"
)!
return-1;
//创建套接字
ListenSocket=socket(AF_INET,SOCK_STREAM,0);
if(ListenSocket==INVALID_SOCKET)
socket函数调用错误,错误号:
WSACleanup();
return-1;
//绑定服务器地址
iResult=bind(ListenSocket,(structsockaddr*)&
local,sizeof(local));
if(iResult==-1)
bind函数调用错误!
错误号:
closesocket(ListenSocket);
//设置函数为监听状态,监听队列长度为NLISTEN
iResult=listen(ListenSocket,SOMAXCONN);
Listen函数调用错误!
quit(ListenSocket);
returnListenSocket;
tcp_server(ULONGuIP,USHORTuPort)
SOCKETListenSocket=INVALID_SOCKET;
memset(&
local,0,sizeof(local));
local.sin_family=AF_INET;
local.sin_addr.S_un.S_addr=htonl(uIP);
local.sin_port=htons(uPort);
clean_up();
tcp_client(char*hname,char*sname)
structsockaddr_inpeer;
SOCKETClientSocket;
//为服务器的地址peer设置用户输入的地址以及端口号
peer,(char*)"
ClientSocket=socket(AF_INET,SOCK_STREAM,0);
if(ClientSocket==INVALID_SOCKET)
//请求建立连接
iResult=connect(ClientSocket,(structsockaddr*)&
peer,sizeof(peer));
connect函数调用错误!
quit(ClientSocket);
returnClientSocket;
tcp_client(ULONGuIP,USHORTuPort)
peer,0,sizeof(peer));
peer.sin_family=AF_INET;
peer.sin_addr.S_un.S_addr=htonl(uIP);
peer.sin_port=htons(uPort);
服务器代码设计:
#defineMAXLINE10000
#defineECHOPORT"
7210"
inttcp_server_fun_echo(SOCKETs)
intiResult=0;
charrecvline[MAXLINE];
do
memset(recvline,0,MAXLINE);
//接收数据
iResult=recv(s,recvline,MAXLINE,0);
if(iResult>
0)
服务器接收到数据:
%s\n"
recvline);
//回射程序已经收到的数据
iResult=send(s,recvline,iResult,0);
if(iResult==SOCKET_ERROR)
send函数调用错误,错误号:
%ld\n"
WSAGetLastError());
iResult=-1;
else
服务器发送数据%s\n"
if(iResult==0)
对方连接关闭,退出\n"
recv函数调用错误,错误号:
break;
}while(iResult>
0);
intmain(intargc,char*argv[])
CSocketFrameframe;
SOCKETListenSocket,ConnectSocket;
//输入参数合法性检查
if(argc!
=1)
usage:
EchoTCPServer"
//初始化
frame.start_up();
//创建服务器的流式套接字并在指定端口号上监听
ListenSocket=frame.tcp_server((char*)NULL,(char*)ECHOPORT);
//改成全部任意
if(ListenSocket==-1)
printf("
服务器准备好回射服务。
。
for(;
;
ConnectSocket=accept(ListenSocket,NULL,NULL);
if(ConnectSocket!
=INVALID_SOCKET)
//建立连接成功
\r\n建立连接成功\n\n"
//回射
iResult=tcp_server_fun_echo(ConnectSocket);
//如果出错,关闭当前连接的套接字,继续接受其他客户端的请求
if(iResult==-1)
当前连接已关闭或出错!
accept函数调用错误,错误号:
frame.quit(ListenSocket);
//关闭套接字
if(closesocket(ConnectSocket)==SOCKET_ERROR)
closesocket函数调用错误,错误号:
frame.quit(ListenSocket);
客户端代码设计:
inttcp_client_fun_echo(FILE*fp,SOCKETs)
charsendline[MAXLINE],recvline[MAXLINE];
//初始化缓冲区
memset(sendline,0,MAXLINE);
memset(recvline,0,MAXLINE);
//循环发送用户输入的数据,并接受服务器返回的应答,直到用户输入Q结束
while(fgets(sendline,MAXLINE,fp)!
if(*sendline=='
Q'
inputend!
//用户发送数据结束
iResult=shutdown(s,SD_SEND);
if(iResult==SOCKET_ERROR)
shutdown函数调用错误,错误号:
%d"
return0;
iResult=send(s,sendline,strlen(sendline),0);
if(iResult==SOCKET_ERROR)
send函数调用错误,错误号:
\r\n客户端发送数据:
%s\r\n"
sendline);
memset(recvline,0,MAXLINE);
iResult=recv(s,recvline,MAXLINE,0);
if(iResult>
0)
客户端收到数据:
recvline);
if(iResult==0)
服务器终止!
recv函数调用错误,错误号:
memset(sendline,0,MAXLINE);
}
intmain(intargc,char*argv[])
if(argc!
=2)
}*/
//WSD初始化
//创建客户端的流式套接字
连接成功,请输入回射字符串。
ClientSocket=frame.tcp_client((char*)argv[1],(char*)ECHOPORT);
if(ClientSocket==-1)
//开始回射请求的发送与接收
iResult=tcp_client_fun_echo(stdin,ClientSocket);
frame.quit(ClientSocket);
实验结果:
我是在两台不同的电脑上做的实验,实验结果如下:
服务器:
客户端:
【实验中出现问题及解决方法】
1.平台的问题
因为自己是使用win10的,开始装上VisualStudio2015出现了很多问题,比如库文件缺失,相关项目类型没有装的问题。
解决方法:
暂时使用DEVC++,然后自己对VS进行相关配置,已经差不多了,后续会尝试转移到VS平台。
【思考问题】
(自己在试验过程中想到的问题)
1.如果服务器端口号设定为任意可不可以?
不可以,因为客户端会不知道服务器的端口。
2.上述设计的服务器有没有考虑多个客户端的问题?
可以多个客户端同时连接成功,但是只有首先连入的那个可以与服务器进行通信!
【实验体会】
因为涉及到网络操作结构类的构造,代码量比较大,当然很多在本节中并没有使用,但考虑到日后要进行使用,减少后续编程的工作量,在本次结构体设计中,对可能用到的基本操作进行了一次性的设计。
但是后续的工作就进行的比较顺利。
还是比较有自豪感的!
因为参考了试验课本,以后仍需勤加练习,才能够更好地掌握流式套接字编程。
成绩
优
良
中
及格
不及格
教师签名:
日期: