服务器回射程序的设计说明.docx

上传人:b****7 文档编号:10196547 上传时间:2023-02-09 格式:DOCX 页数:23 大小:74.07KB
下载 相关 举报
服务器回射程序的设计说明.docx_第1页
第1页 / 共23页
服务器回射程序的设计说明.docx_第2页
第2页 / 共23页
服务器回射程序的设计说明.docx_第3页
第3页 / 共23页
服务器回射程序的设计说明.docx_第4页
第4页 / 共23页
服务器回射程序的设计说明.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

服务器回射程序的设计说明.docx

《服务器回射程序的设计说明.docx》由会员分享,可在线阅读,更多相关《服务器回射程序的设计说明.docx(23页珍藏版)》请在冰豆网上搜索。

服务器回射程序的设计说明.docx

服务器回射程序的设计说明

网络编程技术实验报告

实验名称

实验四    基于数据报套接字的回射程序设计与实验

队 别

姓 名

学 号

实验日期

2015.12.9

实验报告要求:

 1.实验目的    2.实验要求        3.实验环境      4.实验作业      5.问题及解决

6.思考问题    7.实验体会

【实验目的】

1. 巩固套接字编程

2. 熟悉流式套接字编程

【实验要求】

使用流式套接字编程实现回射程序,具体包括:

1.

输出显示。

2.        服务器:

在指定端口上提供服务,接收客户端的发送的回射请求字符串,将接收到的内容回射给

客户端,输出显示。

3.        提炼出网络操作的基本功能,构造网络操作类,修改原有程序

【实验环境】

DEV C++

【实验作业】

网络操作类设计:

class CSocketFrame

{

public:

int start_up();

int clean_up();

int set_address(char *hname,char *sname,struct sockaddr_in *sap,char *protocol);

int quit(SOCKET s);

SOCKET tcp_server(ULONG uIP,USHORT uPort);

SOCKET tcp_server(char *hname,char *sname);

SOCKET tcp_client(char *hname,char *sname);

SOCKET tcp_client(ULONG uIP,USHORT uPort);

};

int CSocketFrame:

:

start_up(void)

{

WORD wVersionRequested;

WSADATA wsaData;

int iResult;

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))

{

printf("无法找到可用的 WSD 版本\n");

WSACleanup();

return -1;

//告诉用户无法找到可用的 WSD

 

}

else

{

printf("WS2.2 初始化成功!

\n");

} */

return 0;

}

int CSocketFrame:

:

clean_up(void)

{

int iResult;

iResult=WSACleanup();

if(iResult==SOCKET_ERROR)

{

//WSACleanup()调用失败

printf("WSACleanup 调用错误,错误号:

%d\n",WSAGetLastError());

return -1;

}

else

printf("Winsocket dll 释放成功!

\n") ;

return 0;

}

int CSocketFrame:

:

set_address(char *hname,char *sname,struct sockaddr_in *sap,char

*protocol)

{

struct servent *sp;

struct hostent *hp;

char *endptr;

unsigned short port;

unsigned long ulAddr=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("未知的主机名,错误号:

%d\n",WSAGetLastError());

return -1;

}

sap->sin_addr=*(struct in_addr *)hp->h_addr;

}

else

sap->sin_addr.S_un.S_addr=ulAddr;

}

else

//如果调用者没有指明一个主机名或地址,则设为通配地址

sap->sin_addr.s_addr=htonl(INADDR_ANY);

//尝试转换 sname 为一个整数

port=(unsigned short)strtol(sname,&endptr,0);

if(*endptr=='\0')

{

//如果成功转化为网络字节序

sap->sin_port=htons(port);

}

else

{

//如果失败,则假定是一个服务名称,通过 getservbyname()函数获得端口号

sp=getservbyname(sname,protocol);

if(sp==NULL)

{

printf("未知服务,错误号:

%d\n",WSAGetLastError());

return -1;

}

sap->sin_port=sp->s_port;

}

return 0;

}

int CSocketFrame:

:

quit(SOCKET s)

{

int iResult=0;

iResult=closesocket(s);

if(iResult==SOCKET_ERROR)

{

printf("closesocket 调用错误,错误号:

%d\n",WSAGetLastError());

return -1;

}

iResult=clean_up();

return iResult;

}

SOCKET CSocketFrame:

:

tcp_server(char *hname,char *sname)

{

SOCKET ListenSocket;

int iResult=0;

sockaddr_in local;

const int on=1;

//为服务器的本机地址设置用户输入的地址以及端口号

if(set_address(hname,sname,&local,(char*)"tcp")!

=0)

return -1;

//创建套接字

ListenSocket=socket(AF_INET,SOCK_STREAM,0);

if(ListenSocket==INVALID_SOCKET)

{

printf("socket 函数调用错误,错误号:

%d\n",WSAGetLastError());

WSACleanup();

return -1;

}

//绑定服务器地址

iResult=bind(ListenSocket,(struct sockaddr *) & local,sizeof(local));

if(iResult==-1)

{

printf("bind 函数调用错误!

错误号:

%d\n",WSAGetLastError());

closesocket(ListenSocket);

WSACleanup();

return -1;

}

//设置函数为监听状态,监听队列长度为 NLISTEN

iResult=listen(ListenSocket,SOMAXCONN);

if(iResult==SOCKET_ERROR)

{

printf("Listen 函数调用错误!

错误号:

%d\n",WSAGetLastError());

quit(ListenSocket);

return -1;

}

return ListenSocket;

}

SOCKET CSocketFrame:

:

tcp_server(ULONG uIP,USHORT uPort)

{

SOCKET ListenSocket=INVALID_SOCKET;

int iResult=0;

sockaddr_in local;

const int on=1;

//为服务器的本机地址设置用户输入的地址以及端口号

memset(&local,0,sizeof(local));

local.sin_family=AF_INET;

local.sin_addr.S_un.S_addr=htonl(uIP);

local.sin_port=htons(uPort);

ListenSocket=socket(AF_INET,SOCK_STREAM,0);

if(ListenSocket==INVALID_SOCKET)

{

printf("socket 函数调用错误,错误号:

%d\n",WSAGetLastError());

clean_up();

return -1;

}

//绑定服务器地址

iResult=bind(ListenSocket,(struct sockaddr *) & local,sizeof(local));

if(iResult==SOCKET_ERROR)

{

printf("bind 函数调用错误!

错误号:

%d\n",WSAGetLastError());

quit(ListenSocket);

return -1;

}

//设置函数为监听状态,监听队列长度为 NLISTEN

iResult=listen(ListenSocket,SOMAXCONN);

if(iResult==SOCKET_ERROR)

{

printf("Listen 函数调用错误!

错误号:

%d\n",WSAGetLastError());

quit(ListenSocket);

return -1;

}

return ListenSocket;

}

SOCKET CSocketFrame:

:

tcp_client(char *hname,char *sname)

{

int iResult=0;

struct sockaddr_in peer;

SOCKET ClientSocket;

//为服务器的地址 peer 设置用户输入的地址以及端口号

if(set_address(hname,sname,&peer,(char *)"tcp")!

=0)

return -1;

//创建套接字

ClientSocket=socket(AF_INET,SOCK_STREAM,0);

if(ClientSocket==INVALID_SOCKET)

{

printf("socket 函数调用错误,错误号:

%d\n",WSAGetLastError());

clean_up();

return -1;

}

//请求建立连接

iResult=connect(ClientSocket,(struct sockaddr *) & peer,sizeof(peer));

if(iResult==SOCKET_ERROR)

{

printf("connect 函数调用错误!

错误号:

%d\n",WSAGetLastError());

quit(ClientSocket);

return -1;

}

return ClientSocket;

}

SOCKET CSocketFrame:

:

tcp_client(ULONG uIP,USHORT uPort)

{

int iResult=0;

struct sockaddr_in peer;

SOCKET ClientSocket;

//为服务器的地址 peer 设置用户输入的地址以及端口号

memset(&peer,0,sizeof(peer));

peer.sin_family=AF_INET;

peer.sin_addr.S_un.S_addr=htonl(uIP);

peer.sin_port=htons(uPort);

//创建套接字

ClientSocket=socket(AF_INET,SOCK_STREAM,0);

if(ClientSocket==INVALID_SOCKET)

{

printf("socket 函数调用错误,错误号:

%d\n",WSAGetLastError());

clean_up();

return -1;

}

//请求建立连接

iResult=connect(ClientSocket,(struct sockaddr *) & peer,sizeof(peer));

if(iResult==SOCKET_ERROR)

{

printf("connect 函数调用错误!

错误号:

%d\n",WSAGetLastError());

quit(ClientSocket);

return -1;

}

return ClientSocket;

}

服务器代码设计:

#define MAXLINE 10000

#define ECHOPORT "7210"

int tcp_server_fun_echo(SOCKET s)

{

int iResult = 0;

char recvline[MAXLINE];

do

{

memset(recvline, 0, MAXLINE);

//接收数据

iResult = recv(s, recvline, MAXLINE, 0);

if (iResult > 0)

{

printf("服务器接收到数据:

%s\n", recvline);

//回射程序已经收到的数据

iResult = send(s, recvline, iResult, 0);

if (iResult == SOCKET_ERROR)

{

printf("send 函数调用错误,错误号:

%ld\n", WSAGetLastError());

iResult = -1;

}

else

printf("服务器发送数据%s\n", recvline);

}

else

{

if (iResult == 0)

printf("对方连接关闭,退出\n");

else

{

printf("recv 函数调用错误,错误号:

%d\n", WSAGetLastError());

iResult = -1;

}

break;

}

} while (iResult > 0);

return iResult;

}

int main(int argc, char* argv[])

{

CSocketFrame frame;

int iResult = 0;

SOCKET ListenSocket, ConnectSocket;

//输入参数合法性检查

if (argc !

= 1)

{

printf("usage:

EchoTCPServer");

return -1;

}

//初始化

frame.start_up();

//创建服务器的流式套接字并在指定端口号上监听

ListenSocket =frame.tcp_server((char *)NULL,(char *)ECHOPORT); //改成全部任意

if (ListenSocket == -1)

return -1;

printf("服务器准备好回射服务。

\n");

for (;;)

{

ConnectSocket = accept(ListenSocket, NULL, NULL);

if (ConnectSocket !

= INVALID_SOCKET)

{

//建立连接成功

printf("\r\n 建立连接成功\n\n");

//回射

iResult = tcp_server_fun_echo(ConnectSocket);

//如果出错,关闭当前连接的套接字,继续接受其他客户端的请求

if (iResult == -1)

printf("当前连接已关闭或出错!

\n");

}

else

{

printf("accept 函数调用错误,错误号:

%d\n", WSAGetLastError());

frame.quit(ListenSocket);

return -1;

}

//关闭套接字

if (closesocket(ConnectSocket) == SOCKET_ERROR)

printf("closesocket 函数调用错误,错误号:

%d\n", WSAGetLastError());

}

frame.quit(ListenSocket);

return 0;

}

客户端代码设计:

#define ECHOPORT "7210"

#define MAXLINE 10000

int tcp_client_fun_echo(FILE *fp,SOCKET s)

{

int iResult;

char sendline[MAXLINE],recvline[MAXLINE];

//初始化缓冲区

memset(sendline,0,MAXLINE);

memset(recvline,0,MAXLINE);

//循环发送用户输入的数据,并接受服务器返回的应答,直到用户输入 Q 结束

while(fgets(sendline,MAXLINE,fp)!

=NULL)

{

if(*sendline=='Q')

{

printf("input end!

\n");

//用户发送数据结束

iResult=shutdown(s,SD_SEND);

if(iResult==SOCKET_ERROR)

{

printf("shutdown 函数调用错误,错误号:

%d",WSAGetLastError());

}

return 0;

}

iResult=send(s,sendline,strlen(sendline),0);

if(iResult==SOCKET_ERROR)

{

printf("send 函数调用错误,错误号:

%d",WSAGetLastError());

return -1;

}

printf("\r\n 客户端发送数据:

%s\r\n",sendline);

memset(recvline,0,MAXLINE);

iResult=recv(s,recvline,MAXLINE,0);

if(iResult>0)

printf("客户端收到数据:

%s\r\n",recvline);

else

{

if(iResult==0)

printf("服务器终止!

\n");

else

printf("recv 函数调用错误,错误号:

%d",WSAGetLastError());

break;

}

memset(sendline,0,MAXLINE);

}

return iResult;

}

int main(int argc,char *argv[])

{

CSocketFrame frame;

int iResult;

SOCKET ClientSocket;

//输入参数合法性检查

/*

if(argc!

=2)

{

printf("usage:

EchoTCPServer");

return -1;

} */

//WSD 初始化

frame.start_up();

//创建客户端的流式套接字

printf("连接成功,请输入回射字符串。

\n");

ClientSocket=frame.tcp_client((char *)argv[1],(char *)ECHOPORT);

if(ClientSocket==-1)

return -1;

//开始回射请求的发送与接收

iResult=tcp_client_fun_echo(stdin,ClientSocket);

frame.quit(ClientSocket);

}

实验结果:

我是在两台不同的电脑上做的实验,实验结果如下:

服务器:

 

客户端:

【实验中出现问题及解决方法】

1. 平台的问题

因为自己是使用 win10 的,开始装上 Visual    Studio 2015 出现了很多问题,比如库文件缺失,

相关项目类型没有装的问题。

解决方法:

暂时使用 DEV C++,然后自己对 VS 进行相关配置,已经差不多了,后续会尝试转移到 VS 平台。

【思考问题】

(自己在试验过程中想到的问题)

1.如果服务器端口号设定为任意可不可以?

不可以,因为客户端会不知道服务器的端口。

2.上述设计的服务器有没有考虑多个客户端的问题?

可以多个客户端同时连接成功,但是只有首先连入的那个可以与服务器进行通信!

【实验体会】

因为涉及到网络操作结构类的构造,代码量比较大,当然很多在本节中并没有使用,但考虑到日后

要进行使用,减少后续编程的工作量,在本次结构体设计中,对可能用到的基本操作进行了一次性的设

计。

但是后续的工作就进行的比较顺利。

还是比较有自豪感的!

因为参考了试验课本,以后仍需勤加练

习,才能够更好地掌握流式套接字编程。

成绩

及格

不及格

教师签名:

                                                                                          日期:

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 城乡园林规划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1