TCPIP实验报告
TCP/IP 技术实验报告书 专 业:[通 信 工 程] 学生姓名:[张 世 超] 完成时间:2020 年 7 月 15 日
实验一 网络应用程序基础 实验目的:
通过实验,使学生熟悉并掌握运用 TCP/IP 技术进行网络编程的基本知识,加深对课堂教学内容的理解,掌握套接字网络通信编程技术,能够运用 VC++为开发工具编程解决网络通信中的实际问题,进行一些简单的网络应用程序设计。实验内容:
1,Winsock 的启动与终止。
2,Winsock 的创建及绑定和关闭。
3,建立通信连接 listen 及 accept 和 connect。
4,数据的传输。
5,简单的客户机/服务器之间的通信。
要求:通过在 SDK 模式下完成数据通信的过程,掌握 Windows Socket 的常用函数的形式和使用方法,理解数据通信的过程。
实验步骤:
1,打开 VC 环境 1,使用向导为客户端创建工程:选择可执行程序,选择使用 wsa 环境,单文档环境,其他的选择默认设置 2,在文件中添加代码 3,编译调试 4,使用向导为服务器端创建工程:选择可执行程序,选择使用 wsa 环境,单文档环境,其他的选择默认设置 5,在文件中添加代码 6,编译调试 7,分别打开两个系统命令窗口中,并分别在其中运行客户端和服务器端程序。
8,在客户端侧输入字符,可以看到服务器收到字符串 参考代码:课本 156 页--160 页 实验结果:
Client: #include<Winsock2.h> #include<stdio.h> //服务器端口号为 5050 #define DEFAULT_PORT 5050 #define DATA_BUFFER 1024 void main(int argc,char *argv[]) {
WSADATA wsaData;
SOCKET sClient;
int iPort=DEFAULT_PORT;
//从服务器端接收的数据长度
int iLen;
//接收数据的缓冲
char buf[DATA_BUFFER];
//服务器端地址
struct sockaddr_in ser;
//判断输入的参数是否正确
if(argc<2)
{
//提示在命令行中输入服务器 IP 地址
printf("Usage:client [server IP address]\n");
return;
}
//接收数据的缓冲区初始化
memset(buf,0,sizeof(buf));
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{
printf("Failed to load Winsock.\n");
return;
}
//填写要连接的服务器地址信息
ser.sin_family=AF_INET;
ser.sin_port=htons(iPort);
//inet_addr()函数将命令行的点分IP地址转换为用二进制表示的网络字节顺序的 IP 地址
ser.sin_addr.s_addr=inet_addr(argv[1]);
//建立客户端流式套接口
sClient=socket(AF_INET,SOCK_STREAM,0);
if(sClient==INVALID_SOCKET)
{
printf("socket() Failed:%d\n",WSAGetLastError());
return;
}
//请求与服务器端建立 TCP 连接
if(connect(sClient,(struct sockaddr*)&ser,sizeof(ser))==INVALID_SOCKET)
{
printf("connect() Failed:%d\n",WSAGetLastError());
return;
}
else
{
//从服务器端接收数据
iLen=recv(sClient,buf,sizeof(buf),0);
if(iLen==0)
return;
else if(iLen==SOCKET_ERROR)
{
printf("recv() Failed:%d",WSAGetLastError());
return;
}
printf("recv() data from server:%s\n",buf);
}
closesocket(sClient);
WSACleanup(); }
Server: #include<Winsock2.h> #include<stdio.h> #include<stdlib.h> #pragma comment(lib,"ws2_32.lib") //服务器使用的端口号为 5050 #define DEFAULT_PORT 5050 void main() {
int iPort=DEFAULT_PORT;
WSADATA wsaData;
SOCKET sListen,
sAccept;
//客户端地址长度
int iLen;
//发送的数据长度
int iSend;
//要发送给客户端的信息
char buf[]="I am a server.";
//服务器和客户端的 IP 地址
struct sockaddr_in ser,
cli;
printf("---------------------------\n");
printf("Server waiting\n");
printf("---------------------------\n");
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{
printf("Failed to load Winsock.\n");
return;
}
//创建服务器端套接口
sListen=socket(AF_INET,SOCK_STREAM,0);
if(sListen==INVALID_SOCKET)
{
printf("socket() Failed:%d\n",WSAGetLastError());
return;
}
//以下建立服务器端地址
ser.sin_family=AF_INET;
//htons()函数把一个双字节的主机直接顺序的数据转换为网络直接顺序的数
ser.sin_port=htons(iPort);
//htonl()函数把一个四字节的主机直接顺序的数据转换为网络直接顺序的数
//使用系统制定的 IP 地址 INADDR_ANY
ser.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(sListen,(LPSOCKADDR)&ser,sizeof(ser))==SOCKET_ERROR)
{
printf("bind() Failed: %d\n",WSAGetLastError());
return;
}
//进入监听状态
if(listen(sListen,5)==SOCKET_ERROR)
{
printf("listen() Failed:%d\n",WSAGetLastError());
return;
}
//初始化客户端地址长度参数
iLen=sizeof(cli);
//进入一个无限循环,等待客户的连接请求
while(1)
{
sAccept=accept(sListen,(struct sockaddr*)&cli,&iLen);
if(sAccept==INVALID_SOCKET)
{
printf("accept() Failed: %d\n",WSAGetLastError());
break;
}
//输出客户 IP 地址和端口号
printf("Accepted client IP:[%s],port:[%d]\n",inet_ntoa(cli.sin_addr),ntohs(cli.sin_port));
//给建立连接的客户发送信息
iSend=send(sAccept,buf,sizeof(buf),0);
if(iSend==SOCKET_ERROR)
{
printf("send() Failed: %d\n",WSAGetLastError());
break;
}
else if(iSend==0)
break;
else
{
printf("send() byte:%d\n",iSend);
printf("---------------------------\n");
}
closesocket(sAccept);
}
closesocket(sListen);
WSACleanup(); } 实验截图:
实验二 基于 TCP 协议的客户/服务器通信程序 实验目的:
通过实验,使学生熟悉并掌握运用 TCP/IP 技术进行网络编程的基本知识,加深对课堂教学内容的理解,掌握套接字网络通信编程技术,能够运用 VC++为开发工具编程解决网络通信中的实际问题,进行一些简单的网络应用程序设计。
实验内容:
1,主机间 TCP 的性能测试之一:回程时延。
2,服务器端能从客户端接收数据并立即将接收到的数据原样返回给客户方。
3,客户端能往服务器端发送数据,然后立即接受从服务器端原样返回的数据。
理解 TCP 通信程序设计过程,并结合特定应用场景(如创建留言板程序、创建多客户端服务器/客户通信程序等)完成程序开发。掌握 TCP 服务器程序和客户程序的创建过程,熟悉单播通信程序中用到的 Winsock 接口,培养学生将所学知识进行灵活运用的能力。
实验步骤:
1,打开 VC 环境 2,使用向导为客户端创建工程:选择可执行程序,选择使用 wsa 环境,单文档环境,其他的选择默认设置 3,在文件中添加代码 4,编译调试 5,使用向导为服务器端创建工程:选择可执行程序,选择使用 wsa 环境,单文档环境,其他的选择默认设置 6,在文件中添加代码 7,编译调试 8,分别打开两个系统命令窗口中,并分别在其中运行客户端和服务器端程序。
9,在客户端着输入字符,可以看到服务器收到字符串
注:可以再实验一的代码上修改,自己增加额外的功能,比如取系统时间,计算往返时间等 作完之后,修改通信代码使用 UDP 来实现网络通信 实验结果:
Client: #include<Winsock2.h> #include<stdio.h> #include<stdlib.h> #define DEFAULT_PORT 5050 #define DATA_BUFFER 1024
#pragma comment(lib,"WS2_32.lib") void main(int argc,char* argv[]) {
WSADATA wsaData;
SOCKET
sClient;
int iPort=5050;
int iLen;
int isend,iRecv;
char send_buf[]="Hello! I am a client";
char recv_buf[DATA_BUFFER];
struct sockaddr_in ser;
if(argc<2)
{
printf("输入服务器的 IP 地址:\n");
return;
}
else
memset(recv_buf,0,sizeof(recv_buf));
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{
printf("Winsock 环境初始化失败:\n");
return;
}
sClient=socket(AF_INET,SOCK_DGRAM,0);
if(sClient==INVALID_SOCKET)
{
printf("socket()函数调用失败:%d\n",WSAGetLastError());
return;
}
ser.sin_family=AF_INET;
ser.sin_port=htons(iPort);
ser.sin_addr.s_addr=inet_addr(argv[1]);
iLen=sizeof(ser);
isend=sendto(sClient,send_buf,sizeof(send_buf),0,(struct sockaddr*)&ser,iLen);
if(isend==SOCKET_ERROR)
{
printf("sendto()函数调用失败:%d\n",WSAGetLastError());
return;
}
else if(isend==0)
return;
else
printf("sendto()调用成功:\n");
iRecv=recvfrom(sClient,recv_buf,sizeof(recv_buf),0,(struct sockaddr*)&ser,&iLen);
if(iRecv==SOCKET_ERROR)
{
printf("recvfrom()函数调用失败:%d\n",WSAGetLastError());
return;
}
else if(iRecv==0)
return;
else
{
printf("sendto():%s\n",recv_buf);
printf("-------------------------------\n");
}
closesocket(sClient);
WSACleanup(); }
Server: #include<Winsock2.h> #include<stdio.h> #include<stdlib.h> #define DEFAULT_PORT 5050 #define BUFFER_LENGTH 1024 #pragma comment(lib,"WS2_32.lib") void main() {
int iPort=DEFAULT_PORT;
WSADATA wsaData;
SOCKET sSocket;
int iLen,iRecv,iSend;
struct sockaddr_in ser,cli;
char send_buf[]="Hollo!I am a server";
char recv_buf[BUFFER_LENGTH];
printf("--------------------");
printf("Server waiting");
printf("--------------------");
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{
printf("环境初始化错误:\n");
return;
}
sSocket=socket(AF_INET,SOCK_DGRAM,0);
if(sSocket==INVALID_SOCKET)
{
printf("socket()函数调用失败:\n",WSAGetLastError());
return;
}
ser.sin_family=AF_INET;
ser.sin_port=htons(iPort);
ser.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(sSocket,(LPSOCKADDR)&ser,sizeof(ser))==SOCKET_ERROR)
{
printf("bind()函数调用失败:\n",WSAGetLastError());
return;
}
iLen=sizeof(cli);
memset(recv_buf,0,sizeof(recv_buf));
while(1)
{
iRecv=recvfrom(sSocket,recv_buf,BUFFER_LENGTH,0,(SOCKADDR*)&cli,&iLen);
if(iRecv==SOCKET_ERROR)
{
printf("recvfrom()函数调用失败:\n",WSAGetLastError());
break;
}
else if(iRecv==0)
break;
else
{
printf("recvfrom():%d\n",recv_buf);
printf(" 客 户 端 的 IP 地 址 、 端 口号:%d\n",inet_ntoa(cli.sin_addr),ntohs(cli.sin_port));
}
iSend=sendto(sSocket,send_buf,sizeof(send_buf),0,(SOCKADDR*)&cli,sizeof(cli));
if(iSend==SOCKET_ERROR)
{
printf("sendto()函数调用失败:\n",WSAGetLastError());
break;
}
else if(iSend==0)
break;
else
{
printf("sendto():调用成功!\n");
}
}
closesocket(sSocket);
WSACleanup(); } 实验截图:
实验三 简易聊天系统的实现
实验目的:
通过实验,使学生熟悉并掌握运用 TCP/IP 技术进行网络编程的基本知识,加深对课堂教学内容的理解,掌握套接字网络通信编程技术,能够运用 VC++为开发工具编程解决网络通信中的实际问题,进行一些简单的网络应用程序设计。
实验内容:
设计实现包括客户端和服务器端的简单聊天系统。
通过编写简单的聊天程序,理解 MFC 的 Socket 类同 Socket API 之间的区别以及MFC 的两种类之间的联系与区别。
实验步骤:
1,打开 VC 环境 2,使用向导为客户端创建工程:选择 FMC 可执行程序,选择使用 wsa 环境,选择单文档环境,其他的选择默认设置 3,为对话窗添加控件:右击工具栏选择控件,拖拽某个控件到对话框 4,为控件添加变量:使用类向导,选择要操作的对话窗类,选择变量 Tab,点击添加变量按钮,为变量命名并选择变量类型。
5,为控件添加代码:右击控件添加事件,如点击,双击,右击。为事件添加代码,根据教科书添加代码 6,添加新的对话窗:单机 rousource Tab, 在对话窗出右击,选择添加对话窗, 7,为对话窗添加类:右键点击新对话窗,选择添加类,出现向导,为类命名并选择父类 8,为心对话窗添加控件和变量 9,为新对话窗添加代码 10, 编译调试
参考代码:课本 224 页--229 页 实验结果:
CsockClient: #include "stdafx.h" #include "CSockClient.h" #include "CSockClientDlg.h"
#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif
///////////////////////////////////////////////////////////////////////////// // CCSockClientApp
BEGIN_MESSAGE_MAP(CCSockClientApp, CWinApp)
//{{AFX_MSG_MAP(CCSockClientApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
//
DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp) END_MESSAGE_MAP()
///////////////////////////////////////////////////////////////////////////// // CCSockClientApp construction
CCSockClientApp::CCSockClientApp() {
// TODO: add construction code here,
// Place all significant initialization in InitInstance }
///////////////////////////////////////////////////////////////////////////// // The one and only CCSockClientApp object
CCSockClientApp theApp;
///////////////////////////////////////////////////////////////////////////// // CCSockClientApp initialization
BOOL CCSockClientApp::InitInstance() {
if (!AfxSocketInit())
{
AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
return FALSE;
}
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
//
of your final executable, you should remove from the following
//
the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls();
// Call this when using MFC in a shared DLL #else
Enable3dControlsStatic(); // Call this when linking to MFC statically #endif
CCSockClientDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
//
dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
//
dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
//
application, rather than start the application"s message pump.
return FALSE; }
CsockServer: #include "stdafx.h" #include "CsockServer.h" #include "CsockServerDlg.h"
#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
///////////////////////////////////////////////////////////////////////////// // CCsockServerApp
BEGIN_MESSAGE_MAP(CCsockServerApp, CWinApp)
//{{AFX_MSG_MAP(CCsockServerApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
//
DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp) END_MESSAGE_MAP()
///////////////////////////////////////////////////////////////////////////// // CCsockServerApp construction
CCsockServerApp::CCsockServerApp() {
// TODO: add construction code here,
// Place all significant initialization in InitInstance }
///////////////////////////////////////////////////////////////////////////// // The one and only CCsockServerApp object
CCsockServerApp theApp;
///////////////////////////////////////////////////////////////////////////// // CCsockServerApp initialization
BOOL CCsockServerApp::InitInstance() {
if (!AfxSocketInit())
{
AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
return FALSE;
}
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
//
of your final executable, you should remove from the following
//
the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls();
// Call this when using MFC in a shared DLL #else
Enable3dControlsStatic(); // Call this when linking to MFC statically #endif
CCsockServerDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
//
dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
//
dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
//
application, rather than start the application"s message pump.
return FALSE; } 实验截图:
实验四 WinInet 实现 FTP 客户端 实验目的:
通过实验,使学生熟悉并掌握运用 TCP/IP 技术进行网络编程的基本知识,加深对课堂教学内容的理解,掌握套接字网络通信编程技术,能够运用 VC++为开发工具编程解决网络通信中的实际问题,进行一些简单的网络应用程序设计。
实验内容:
1,写出完整的软件需求说明书。
2,开发 FTP 的客户端。
3,完成在局域网内的测试,并记录测试结果。
本实验涵盖了 C/S 体系结构和 Socket 编程。通过本实验深入地了解 FTP 的工作原理以及服务器端和客户端的工作流程,学习 Socket 在网络编程中的各种应用,掌握 WinInet 的套接字编程。
实验步骤:
1,打开 VC 环境 2,使用向导为客户端创建工程:选择 MFC 可执行程序,单文档环境,其他的选择默认设置 3,为对话窗添加控件:右击工具栏选择控件,拖拽某个控件到对话框 4,为控件添加变量:使用类向导,选择要操作的对话窗类,选择变量 Tab,点击添加变量按钮,为变量命名并选择变量类型。
5,为控件添加代码:右击控件添加事件,如点击,双击,右击。为事件添加代码,根据教科书添加代码 6,编译调试 实验结果:
Scan: #include "stdafx.h" #include "scan.h" #include "scanDlg.h"
#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif
///////////////////////////////////////////////////////////////////////////// // CScanApp
BEGIN_MESSAGE_MAP(CScanApp, CWinApp)
//{{AFX_MSG_MAP(CScanApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
//
DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp) END_MESSAGE_MAP()
///////////////////////////////////////////////////////////////////////////// // CScanApp construction
CScanApp::CScanApp() {
// TODO: add construction code here,
// Place all significant initialization in InitInstance }
///////////////////////////////////////////////////////////////////////////// // The one and only CScanApp object
CScanApp theApp;
///////////////////////////////////////////////////////////////////////////// // CScanApp initialization
BOOL CScanApp::InitInstance() {
// Standard initialization
// If you are not using these features and wish to reduce the size
//
of your final executable, you should remove from the following
//
the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls();
// Call this when using MFC in a shared DLL #else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
CScanDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
//
dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
//
dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
//
application, rather than start the application"s message pump.
return FALSE; } 实验截图: