计算机网络实验报告2.docx

上传人:b****5 文档编号:3400713 上传时间:2022-11-22 格式:DOCX 页数:22 大小:64.36KB
下载 相关 举报
计算机网络实验报告2.docx_第1页
第1页 / 共22页
计算机网络实验报告2.docx_第2页
第2页 / 共22页
计算机网络实验报告2.docx_第3页
第3页 / 共22页
计算机网络实验报告2.docx_第4页
第4页 / 共22页
计算机网络实验报告2.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

计算机网络实验报告2.docx

《计算机网络实验报告2.docx》由会员分享,可在线阅读,更多相关《计算机网络实验报告2.docx(22页珍藏版)》请在冰豆网上搜索。

计算机网络实验报告2.docx

计算机网络实验报告2

《计算机网络》课程实验报告

实验二:

Socket通信编程

姓名

院系

计算机学院

学号

任课教师

钱权,张瑞,袁世忠

指导教师

张瑞

实验地点

计605

实验时间

周五5-6节

实验课表现

出勤、表现得分(10)

实验报告

得分(40)

实验总分

操作结果得分(50)

实验目的:

1.掌握Socket编程过程;

2.编写简单的网络应用程序。

实验内容:

利用你选择的任何一个编程语言,分别基于TCP和UDP编写一个简单的Client/Server网络应用程序。

具体程序要求参见《实验指导书》。

要求以附件形式给出:

●系统概述:

运行环境、编译、使用方法、实现环境、程序文件列表等;

●主要数据结构;

●主要算法描述;

●用户使用手册;

●程序源代码;

实验要求:

(学生对预习要求的回答)(10分)

得分:

●Socket编程客户端的主要步骤

1、用socket()函数创建socket

2、设置目标服务器的IP地址和端口号

3、用connect()函数,与目标服务器连接

4、用Send()函数发送数据,recv()函数接收数据

5、关闭socket

●Socket编程服务器端的主要步骤

1、用socket()函数创建socket

2、用Bind()函数将socket与本机上的一个端口相关联

3、用Listen()函数使socket处于监听模式

4、用accept()函数让服务器接收客户的连接请求

5、用Send()函数发送数据,recv()函数接收数据

6、关闭socket

实验过程中遇到的问题如何解决的?

(10分)

得分:

问题1:

设置IP地址时,刚开始设置成自己的本机的IP地址,但是将程序放到另一台电脑上时就需要修改IP地址。

后来将IP地址设置成127.0.0.1就解决了这一问题。

127.0.0.1是回送地址,指本地机,这样就不用改变本机地址了。

问题2:

做完基于TCP的Client/Server编程后,在做基于UDP的编程的时候,以为在TCP的基础上,只要去掉连接服务器、监听、接受连接请求这些步骤就可以,结果无法实现自己想要的效果。

后来发现UDP还有一些地方与TCP的不同,比如发送、接收数据的函数是sendto()、

recvfrom(),而不是send()、recv(),仔细查看课UDP的相关资料后也就实现了这一程序。

本次实验的体会(结论)(10分)

得分:

这次SOCKET编程一开始觉得无从下手,在网上找了好多资料才了解了socket的用法,仔细研究了之后发现只要掌握了客户端和服务端各自的运行规律,编写程序意外的简单。

通过这次实验我明白了看问题一定要看本质,不能被看似很难的问题吓到。

我一定会再接再厉,争取做好每一次实验。

思考题:

(10分)

思考题1:

(4分)

得分:

你所用的编程语言在Socket通信中用到的主要类及其主要作用。

1.socket类:

用于服务器端程序和客户端程序,实现双方的数据通信。

2.SOCKADDR_IN结构:

记录端口地址、IP地址、协议族等信息。

思考题2:

(6分)

得分:

说明TCP和UDP编程的主要差异和特点。

TCP和UDP是Socket的两种主要操作方式:

面向连接的和无连接的。

无连接的操作使用UDP数据报协议,这个操作不需要连接一个目的的socket,它只是简单地投出数据报,快速高效,但缺少数据安全性。

而面向连接的操作使用TCP协议,一个这个模式的socket必须在发送数据之前与目的地的socket取得一个连接,一旦连接建立了,socket就可以使用一个流接口:

打开-读-写-关闭,所有的发送的信息都会在另一端以同样的顺序被接收,面向连接的操作比无连接的操作效率要低,但数据的安全性更高。

基于TCP的socket编程是采用的流式套接字(SOCK_STREAM)。

基于UDP采用的数据报套接字(SOCK_DGRAM).流式套接字的设计是针对面向连接的网络应用,在数据传输之前需要预先建立连接,在数据传输过程中需要维持连接,在数据传输结束后需要释放连接。

由于采用校验和、确认与超时等差错控制手段,因此流式套接字可以保证数据传输的正确性。

数据报套接字(SOCK_DGRAM)提供无连接的、不可靠的数据传输服务,实际上它是基于TCP/IP协议族中的UDP协议实现的。

数据报套接字提供无序、有差错与有重复的数据流服务。

数据报套接字的设计是针对无连接的网络应用,在数据传输之前不需要预先建立连接。

由于只采用很有限的差错控制手段,因此数据报套接字无法保证数据传输的正确性。

所以TCP面向连接,安全可靠,而UDP面向数据,数据可能会丢失,但是高效,结构简单,网络开销小。

指导教师评语:

日期:

附件:

(一)系统概述

1.运行环境:

windowXP、win7等操作系统

2.编译:

已编译完成,可直接执行可执行文件

3.实现环境:

VisualStudio2010

4.使用方法:

一般窗口应用程序,双击即可运行。

(用户名:

aaa密码:

123)

(二)主要数据结构

服务器端程序:

1.ClassCClientNet{

public:

//连接上指定服务器

intConnect(intport,constchar*address);

//发送信息

//intSendMsg(constchar*msg,intlen);

voidSendMsg();

//关闭

VoidClose();

private:

SOCKETm_sock;

}

2.SOCKET

3.WSAData

4.sockaddr_in

客户端程序:

1.classCServerNet

{

public:

//初始化服务器,返回0表示成功

intInit(constchar*address,intport);

//更新数据

voidRun();

private:

SOCKETm_sock;

}

2.SOCKET

3.WSAData

4.sockaddr_in

(三)用户使用手册

1.运行服务器端程序server.exe。

2.运行客户端程序client.exe。

3.用户登录:

在客户端界面中出现connect则说明可以与服务器连接。

在login:

后输入用户名(aaa),若用户名存在则client端返回该用户名的密码(123),与输入密码比对,若相同则连接成功,可以开始发送消息。

4.发送消息:

在步骤3后,用户端界面会出现“sendyourmessage:

”的提示,此时可以输入想要发送的消息,输完后按enter键发送。

若发送成功,则server界面出现发送的消息,client界面提示“sendsuccessfully”。

5.退出连接:

输入exit并按enter键断开与服务器的连接,服务器端界面和客户端界面同时提示“exit\nclose”。

(四)算法分析

ClientServer

(五)程序源代码

A.TCP

1.Client端

#pragmaonce

#include

#include

#pragmacomment(lib,"Ws2_32.lib")

classCClientNet

{

public:

//连接上指定服务器

intConnect(intport,constchar*address);

//发送信息

//intSendMsg(constchar*msg,intlen);

voidSendMsg();

//关闭

voidClose();

private:

SOCKETm_sock;

};

 

intCClientNet:

:

Connect(intport,constchar*address)

{

intrlt=0;

//用于记录错误信息并输出

intiErrMsg;

//启动WinSock

WSADatawsaData;

iErrMsg=WSAStartup(MAKEWORD(1,1),&wsaData);

if(iErrMsg!

=NO_ERROR)

{

printf("failedwithwsaStartuperror:

%d\n",iErrMsg);

rlt=1;

returnrlt;

}

//创建Socket

m_sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

if(m_sock==INVALID_SOCKET)

//创建Socket失败

{

printf("socketfailedwitherror:

%d\n",WSAGetLastError());

rlt=2;

returnrlt;

}

//目标服务器数据

sockaddr_insockaddrServer;

sockaddrServer.sin_family=AF_INET;

sockaddrServer.sin_port=port;//端口号

sockaddrServer.sin_addr.s_addr=inet_addr(address);//将一个点分十进制的IP转换成一个长整数型数

//连接,sock与目标服务器连接

iErrMsg=connect(m_sock,(sockaddr*)&sockaddrServer,sizeof(sockaddrServer));

if(iErrMsg<0)

{

printf("connectfailedwitherror:

%d\n",iErrMsg);

rlt=3;

returnrlt;

}

returnrlt;

}

voidCClientNet:

:

SendMsg()

{

chara[50];

charb[50];

charc[50];

printf("login:

\n");

gets(b);

send(m_sock,b,sizeof(b),0);

charrecvBuf[50];

recv(m_sock,recvBuf,50,0);

printf("%s\n",recvBuf);

gets(c);

send(m_sock,c,sizeof(c),0);

recv(m_sock,recvBuf,50,0);

printf("%s\n",recvBuf);

while

(1)

{

gets(a);

if(strcmp(a,"exit")==0)

{

send(m_sock,a,sizeof(a),0);

break;

}

else

{

send(m_sock,a,sizeof(a),0);

charrecvBuf[50];

recv(m_sock,recvBuf,50,0);

printf("%s\n",recvBuf);

}

}

}

voidCClientNet:

:

Close()

{

closesocket(m_sock);

}

 

voidmain()

{

CClientNetclient;

//连接到127.0.0.1(即本地),端口号为8888的服务端

printf("Connect\n");

client.Connect(8888,"127.0.0.1");

//发送消息

client.SendMsg();

//关闭socket

printf("close\n");

client.Close();

system("pause");

}

2.Server端

#pragmaonce

#include

#include

#pragmacomment(lib,"ws2_32.lib")

classCServerNet

{

public:

//初始化服务器,返回0表示成功

intInit(constchar*address,intport);

//更新数据

voidRun();

private:

SOCKETm_sock;

};

intCServerNet:

:

Init(constchar*address,intport)

{

intrlt=0;

//用于记录错误信息,并输出

intiErrorMsg;

//初始化WinSock

WSADatawsaData;

iErrorMsg=WSAStartup(MAKEWORD(1,1),&wsaData);

if(iErrorMsg!

=NO_ERROR)

{

//初始化WinSock失败

printf("wsastartupfailedwitherror:

%d\n",iErrorMsg);

rlt=1;

returnrlt;

}

//创建服务端Socket

m_sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

if(m_sock==INVALID_SOCKET)

{

//创建Socket异常

printf("socketfailedwitherror:

%d\n",WSAGetLastError());

rlt=2;

returnrlt;

}

//声明信息

sockaddr_inserverAddr;

serverAddr.sin_family=AF_INET;

serverAddr.sin_port=port;

serverAddr.sin_addr.s_addr=inet_addr(address);

//绑定

iErrorMsg=bind(m_sock,(sockaddr*)&serverAddr,sizeof(serverAddr));

if(iErrorMsg<0)

{

//绑定失败

printf("bindfailedwitherror:

%d\n",iErrorMsg);

rlt=3;

returnrlt;

}

returnrlt;

}

voidCServerNet:

:

Run()

{

//公开连接

listen(m_sock,5);

sockaddr_intcpAddr;

intlen=sizeof(sockaddr);

SOCKETnewSocket;

charbuf[1024];

intrval;

characc[]="aaa";

charpawd[]="123";

intcomp1,comp2,flag1=1,flag2=1;

SOCKETsockConn=accept(m_sock,(sockaddr*)&tcpAddr,&len);

while(flag1==1)

{

charrecvBuf1[50];

recv(sockConn,recvBuf1,50,0);

comp1=strcmp(recvBuf1,acc);

if(comp1==0)

{

send(sockConn,"password:

",strlen("password:

")+1,0);

flag1=0;

}

else

{

send(sockConn,"usernamedoesn'texist,pleaseloginagain:

",strlen("usernamedoesn'texist,pleaseloginagain:

")+1,0);

}

}

while(flag2==1)

{

charrecvBuf2[50];

recv(sockConn,recvBuf2,50,0);

comp2=strcmp(recvBuf2,pawd);

if(comp2==0)

{

send(sockConn,"sendyourmessage:

",strlen("sendyourmessage:

")+1,0);

flag2=0;

}

else

{

send(sockConn,"wrongpassword,pleasetypethepasswordagain:

",strlen("wrongpassword,pleasetypethepasswordagain:

")+1,0);

}

}

while

(1)

{

charrecvBuf[50];

recv(sockConn,recvBuf,50,0);

if(strcmp(recvBuf,"exit")==0)

{

printf("%s\n",recvBuf);

break;

}

else

{

printf("%s\n",recvBuf);

charsendBuf[50];

sprintf(sendBuf,"sendsuccessfully");

send(sockConn,sendBuf,strlen(sendBuf)+1,0);

}

}

//关闭自身的Socket

printf("close\n");

closesocket(m_sock);

}

intmain(intargc,char**argv)

{

CServerNetserverNet;

intiRlt=serverNet.Init("127.0.0.1",8888);

if(iRlt==0)

{

printf("initok...\n");

serverNet.Run();

}

else

printf("serverNetinitfailedwitherror:

%d\n",iRlt);

system("pause");

}

B.UDP

1.Client端

#pragmaonce

#include

#include

usingnamespacestd;

#pragmacomment(lib,"ws2_32.lib")

voidmain()

{

structsockaddr_inm_lsockaddr;

structsockaddr_inm_rsockaddr;

SOCKETm_connectSocket;

memset(&m_lsockaddr,0,sizeof(structsockaddr_in));

//--------初始化winsock环境-------------

WSADATAwsaD;

intresult=WSAStartup((WORD)(1<<8|1),&wsaD);//初始化WinSocket动态连接库;

if(result!

=0)//初始化失败;

{

return;

}

//---------创建一个鉴听SOCKET句柄-----------

if((m_connectSocket=socket(AF_INET,SOCK_DGRAM,0))==INVALID_SOCKET)

{

return;

}

//---------绑定到指定的主机与端口号----------

memset(&m_rsockaddr,0,sizeof(structsockaddr_in));

m_lsockaddr.sin_family=AF_INET;

m_lsockaddr.sin_addr.s_addr=inet_addr("127.0.0.1");

m_lsockaddr.sin_port=htons(7070);

if(bind(m_connectSocket,(SOCKADDR*)&m_lsockaddr,sizeof(structsockaddr_in))==SOCKET_ERROR)

{

return;

}

//---------发送信息给服务器--------------

chara[50];

charb[50];

charc[50];

charrecvBuf[50];

intret=0;

intlen=sizeof(structsockaddr_in);

cout<<"login:

"<

gets(b);

memset(&m_lsockaddr,0,sizeof(structsockaddr_in));

m_rsockaddr.sin_family=AF_INET;

m_rsockaddr.sin_addr.s_addr=inet_addr("127.0.0.1");

m_rsockaddr.sin_port=htons(8080);

if(sendto(m_connectSocket,b,strlen(b),0,(SOCKADDR*)&m_rsockaddr,sizeof(structsockaddr_in))==SOCKET_ERROR)

{

return;

}

ret=recvfrom(m_connectSocket,recvBuf,50,0,(SOCKADDR*)&m_rsockaddr,&len);

if(ret==SOCKET_ERROR)

{

return;

}

recvBuf[ret]='\0';

cout<

gets(c);

if(sendto(m_connectSocket,c,strlen(c),0,(SOCKADDR*)&m_rsockaddr,sizeof(structsockaddr_in))==SOCKET_ERROR)

{

return;

}

ret=recvfrom(m_connectSocket,recvBuf,50,0,(SOCKADDR*)&m_rsockaddr,&len);

if(ret==SOCKET_ERROR)

{

return;

}

recvBuf[ret]='\0';

cout<

while

(1)

{

gets(

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

当前位置:首页 > 小学教育 > 学科竞赛

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

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