实验报告
学院(系)名称:计算机科学与工程学院
姓名
班级
课程名称
实验时间
学号
实验
项目
专业
信息安全
实验二:基于 TCP/UDP 的 Socket 编程
计算机网络原理
课程
代码
实验
地点
考 核
标 准
实验准备(实验
实验过程(实验方
实 验 报 告 (实 验 内
实验结果(结论正
目的/工具熟悉
案可行性及步骤完
容丰富度与格式清
确性以及分析合理
成绩
情况)10 分
整性)40 分
晰度) 30 分
性)20 分
考核
内容
评 价 实 验 目 的
是否明确,实验
工 具 是 否 清 晰
了 解 以 及 熟 悉
情况
○可行,完整
○可行,不完整
○丰富,清晰
○较丰富,较清晰
○不可行,不完整
○丰富,不清晰
○不丰富,不清晰
○结论正确,分析
合理
○结论正确,分析
不充分
○结论不正确,分
析不合理
教师签字:
一、实验目的
熟悉和掌握 socket 编程的基本理论和方法。掌握基于 TCP 和 UDP 的工作原理以及 Socket 编程的一般方法,
能够编写简单的网络应用程序。
二、实验要求
请在以下题目中选择一个,按照要求完成实验,并完成实验报告。实验可以分组进行,每 2 人一组,
在报告中注明每个成员的分工。编程可以使用任何高级语言,建议使用 java 或 C++。
三、实验选题
实验 2.1:基于 TCP and UDP 的 socket 编程
1、
实验内容:
a) 利用 Java 或 C++语言,分别基于 TCP 和 UDP 编写一个简单的 Client/Server 网络应用程序。
要求实现客户向服务器传输任意一个字符串,服务器将收到的字符串变换成大写后传回客户。
b) 修改上述程序,实现服务器根据客户请求,将服务器端指定的文件可靠地传输给客户。如果
服务器没有指定的文件,服务器将给客户返回一个信息,通知客户其请求文件不存在。
c) 有条件的同学可以进一步改进 b)的程序,使之更实用。比如可以请求服务器先传输目录,然
后客户根据目录请求传输文件等。
第 1页 共 21页
2、 实验报告:在实验报告中要说明 Socket 编程的客户端和服务器端主要步骤、利用 Java 语言用到
的主要类及其主要作用、TCP 和 UDP 编程的主要差异和特点、你所实现的文件传输的程序代码、
实验过程和实验结果。
四、实验过程及步骤
1.实验说明
操作系统:Win7
编程语言:C++
使用工具: VC6.0
2.实验原理
(1)基于 Socket 进行通信过程:
a.服务器程序将一个套接字绑定到一个特定的端口,并通过此套接字等待和监听客户的连接
请求;
b.客户程序根据服务器程序所在的主机和端口号发出连接请求;
c.如果一切正常,服务器接受连接请求。并获得一个新的绑定到不同端口地址的套接字;
d.客户和服务器通过读、写套接字进行通讯。
(2)基于 TCP 的 Socket 通信过程:
服务器端先初始化 Socket,然后与端口绑定(bind),对端口进行监听(listen),调用 accept 阻塞,等待客
户端连接。在这时如果有个客户端初始化一个 Socket,然后连接服务器(connect),如果连接成功,这时客
第 2页 共 21页
户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据
发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。
(3)基于 UDP 的 Socket 通信过程:
服务器先创建 socket,将 socket 绑定(bind)一个本地地址和端口上,等待数据传输(recvfrom)。这
个时候如果有个客户端创建 socket,并且向服务器发送数据(sendto),服务器就建立了连接,实现了数
据的通信,连接结束后关闭连接。
(4)进程间的 C/S 通信模式:
在 TCP/IP 网络应用中,通信的两个进程间相互作用的主要模式是客户机/服务器模式
(client/server),即客户像服务其提出请求,服务器接受到请求后,提供相应的服务。
服务器:
(1)首先服务器方要先启动,打开一个通信通道并告知本机,它愿意在某一地址和端口上接
收客户请求
(2)等待客户请求到达该端口
(3)接收服务请求,处理该客户请求,服务完成后,关闭此新进程与客户的通信链路,并终
止
(4)返回第二步,等待另一个客户请求
(5)关闭服务器
客户方:
(1)打开一个通信通道,并连接到服务器所在的主机特定的端口
第 3页 共 21页
(2)向服务器发送请求,等待并接收应答,继续提出请求
(3)请求结束后关闭通信信道并终止
3.实验步骤及源码
(1)基于 TCP 协议的 Socket 编程(功能:输入小写字母返回大写字母)
要求:实现客户向服务器传输任意一个字符串,服务器将收到的字符串变换成大写后传回客户。
环境:
客户端(Client)
服务器(Server)
IP 地址
127.0.0.1
127.0.0.1
监听端口
9999
6666
TCP_Server.cpp 源码参考:
#include
#include
#include //WindowsSocket 编程头文件
#include
#include
#include
#include
#pragma comment(lib,"ws2_32.lib")//链接 ws2_32.lib 库文件到此项目中
using namespace std;
//================全局常量==================
//创建缓冲区
const int BUF_SIZE = 2048;
//================全局变量==================
SOCKET sockSer, sockCli;
SOCKADDR_IN addrSer, addrCli; //address
int naddr = sizeof(SOCKADDR_IN);
char sendbuf[BUF_SIZE];
char inputbuf[BUF_SIZE];
char recvbuf[BUF_SIZE];
//================函数声明==================
int main() {
cout << "=>Start the Server!" << endl;
//加载 socket 库
第 4页 共 21页
WSADATA wsadata;
if (WSAStartup(MAKEWORD(2, 2),&wsadata) != 0)
{
//输出出错信息
cout << "=>Failed to load socket library!" << endl;
system("pause");
return 0;
}
else {
cout << "=>Successfully loaded socket library!" << endl;
}
//创建 Soucket;
sockSer = socket(AF_INET, SOCK_STREAM, 0);
//描述协议族,INET 属于 ipv4;
//sock_stream 创建套接字类型:tcp;
//0 不指定协议,常用的协议有 tcp、udp 等
//初始化地址包
addrSer.sin_addr.s_addr = inet_addr("127.0.0.1");
addrSer.sin_family = AF_INET;
addrSer.sin_port = htons(6666);
//绑定 Socket(bind)
bind(sockSer, (SOCKADDR*)&addrSer, sizeof(SOCKADDR));
//强制将 SOCKADDR_INET 转化成 SOCKEADDR
//监听
while (true) {
cout << "=>Start to connect!" << endl;
//监听连接请求;
listen(sockSer,5);
//等待连接最大数:5
//接受连接
sockCli=accept(sockSer, (SOCKADDR*)&addrCli, &naddr);
if (sockCli != INVALID_SOCKET) {
while (true)
{
cout << "=>The client connects successfully!" << endl;
recv(sockCli, recvbuf, sizeof(recvbuf), 0);
cout << "=>Lowercase Message received:" << recvbuf << endl;
cout << "=>Upper message return to the client:" << endl;
int i=0;
for(;i<=strlen(recvbuf)-1;i++)
第 5页 共 21页
{
}
recvbuf[i]=toupper(recvbuf[i]);
send(sockCli, recvbuf, sizeof(sendbuf), 0);
//strcpy(sendbuf, "hello");
//send(sockCli, sendbuf, sizeof(sendbuf), 0);
//接收客户端发来信息
}
}
else
{
}
cout << "=>Connection failed!" << endl;
}
closesocket(sockSer);
closesocket(sockCli);
return 0;
}
TCP_Client.cpp 源码参考:
#include
#include
#include //WindowsSocket 编程头文件
#include
#include
#pragma comment(lib,"ws2_32.lib")//链接 ws2_32.lib 库文件到此项目中
using namespace std;
//================全局常量==================
//创建缓冲区
const int BUF_SIZE = 2048;
//================全局变量==================
SOCKET sockSer, sockCli;
SOCKADDR_IN addrSer, addrCli; //address
int naddr = sizeof(SOCKADDR_IN);
char sendbuf[BUF_SIZE];
char inputbuf[BUF_SIZE];
char recvbuf[BUF_SIZE];
//================函数声明==================
第 6页 共 21页
int main() {
//加载 socket 库
cout << "=>Start the Client!" << endl;
WSADATA wsadata;
if (WSAStartup(MAKEWORD(2, 2),&wsadata) != 0)
{
//输出出错信息
cout << "=>Failed to load socket library!" << endl;
system("pause");
return 0;
}
else {
cout << "=>Successfully loaded socket library!" << endl;
}
//创建 Soucket;
sockCli = socket(AF_INET, SOCK_STREAM, 0);
//描述协议族,INET 属于 ipv4;
//sock_stream 创建套接字类型:tcp;
//0 不指定协议,常用的协议有 tcp、udp 等
//初始化客户端地址
addrCli.sin_addr.s_addr = inet_addr("127.0.0.1");
addrCli.sin_family = AF_INET;
addrCli.sin_port = htons(9999);
//初始化服务器地址
addrSer.sin_addr.s_addr = inet_addr("127.0.0.1");
addrSer.sin_family = AF_INET;
addrSer.sin_port = htons(6666);
while (true)
{
if (connect(sockCli, (SOCKADDR*)&addrSer, sizeof(addrSer))!=SOCKET_ERROR)
{
while (true)
{
cout << "=>The client connects successfully!" << endl;
cout << "=>Enter the lowercase message to be sent:" << endl;
cin >> sendbuf;
send(sockCli, sendbuf, sizeof(sendbuf), 0);
cout << "=>Sent successfully!" << endl;
recv(sockCli, recvbuf, sizeof(recvbuf), 0);
cout << "=>Upper message returned by the server:" << recvbuf << endl;
}
第 7页 共 21页
}
else
{
}
//cout << "=>Client connection failed!" << endl;
}
closesocket(sockSer);
closesocket(sockCli);
return 0;
}
实验结果截图:
(2)基于 UDP 协议的 Socket 编程(功能:输入小写字母返回大写字母)
要求:实现客户向服务器传输任意一个字符串,服务器将收到的字符串变换成大写后传回客户。
环境:
客户端(Client)
服务器(Server)
IP 地址
127.0.0.1
127.0.0.1
监听端口
6666
6666
UDP_Server.cpp 源码参考:
#include
#include
第 8页 共 21页