基于UDP的文件传输实验报告

更新时间:2023-09-17 02:37:01 阅读量: 高中教育 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

《数据库技术 》实验报告 授课教师:张国富 苏兆品 zgf@hfut.edu.cn

实验报告

课程名称 《数据库技术》

学生姓名 ***

学 号 ********

专业班级 电子信息工程

指导教师

成 绩

2015年6月 8 日

《数据库技术 》实验报告 授课教师:张国富 苏兆品 zgf@hfut.edu.cn

实验名称: 基于UDP的文件传输 1.实验目的

(1) 熟练掌握Socket编程; (2) 分析UDP与TCP的异同。

2.实验设备和条件

硬件环境:PC机

操作系统: Windows 或者 Linux

语言环境: Visual C++ ,VS,GCC,Java均可

3.实验要求

参考TCP文件传输demo, 基于UDP实现send.mp3文件的传输,并测试接收到的文件与发送的文件是否一致。

请各位同学于第15周星期三或星期四上课时将纸质版(双面打印)上交!

4.实验内容:测试数据与实验结果(可以抓图粘贴)

(1)发送端代码。

#include \ #include #include

#define MAX_LENGTH 1024

int _tmain(int argc, _TCHAR* argv[]) {

exit(-1);

if (WSAStartup(wVersionRequested, &wsaData) != 0)//初始化ws2_32.dll动态库 {

printf(\);//Winsock初始化错误 wVersionRequested = MAKEWORD(2, 2); WSADATA wsaData; WORD wVersionRequested;

《数据库技术 》实验报告 授课教师:张国富 苏兆品 zgf@hfut.edu.cn

}

if (wsaData.wVersion != wVersionRequested) { }

//说明ws2_32.dll正确加载

printf(\); //创建套接字 SOCKET servsock; printf(\);

servsock = socket(AF_INET, SOCK_DGRAM, 0);//数据报套接字 int servport = 5555; int iSockErr = 0; //定义服务器地址结构 sockaddr_in udpaddr; int len = sizeof(udpaddr);

memset(&udpaddr, 0, sizeof(udpaddr)); udpaddr.sin_family = AF_INET; udpaddr.sin_port = htons(servport);

//将一个点分十进制IP地址字符串转换成32位数字表示的IP地址 udpaddr.sin_addr.s_addr = inet_addr(\);////INADDR_ANY

printf(\);//Winsock版本不匹配 WSACleanup();//结束对ws2_32.dll的调用 exit(-2);

//读取mp3文件 FILE *fp = NULL; errno_t err;

err = fopen_s(&fp, \七里香.mp3\, \); if (fp == NULL){ }

char buffer[MAX_LENGTH] = \;

printf(\); getchar(); exit(-5);

《数据库技术 》实验报告 授课教师:张国富 苏兆品 zgf@hfut.edu.cn

char *bufptr = buffer; int i = 0; while (!feof(fp)) { }

sendto(servsock, \, 0, 0, (struct sockaddr*)&udpaddr, len);

int iBytesRead = fread(bufptr, 1, MAX_LENGTH, fp);

int iRet = sendto(servsock, buffer, sizeof(buffer), 0, (struct sockaddr*)&udpaddr, len); if (iRet != SOCKET_ERROR) { } else { }

if (iRet == SOCKET_ERROR) { }

else if (iRet == 0) { }

if (iBytesRead == 0) { }

//printf(\

printf(\, i++, iBytesRead); Sleep(10);

printf(\); break;

printf(\); break;

//closesocket(clisock); printf(\); break;

printf(\); break;

iRet = recvfrom(servsock, buffer, sizeof(buffer), 0, (struct sockaddr*)&udpaddr, &len);

《数据库技术 》实验报告 授课教师:张国富 苏兆品 zgf@hfut.edu.cn

}

//关闭

shutdown(servsock, 2); closesocket(servsock); WSACleanup(); getchar(); return 0;

(2)接收端代码。

#include \ #include #include

#define MAX_LENGTH 1024*10

int _tmain(int argc, _TCHAR* argv[]) {

//说明ws2_32.dll正确加载

printf(\); }

exit(-2);

WSACleanup();//结束对ws2_32.dll的调用 if (wsaData.wVersion != wVersionRequested) {

printf(\);//Winsock版本不匹配 }

exit(-1);

if (WSAStartup(wVersionRequested, &wsaData) != 0)//初始化ws2_32.dll动态库 {

printf(\);//Winsock初始化错误 wVersionRequested = MAKEWORD(2, 2); WSADATA wsaData; WORD wVersionRequested;

《数据库技术 》实验报告 授课教师:张国富 苏兆品 zgf@hfut.edu.cn

//获取本机IP地址 char PCname[100] = { \ }; char *IPaddress = NULL;

gethostname(PCname, sizeof(PCname)); printf(\, PCname);

struct hostent FAR * lpHostEnt = gethostbyname(PCname); if (lpHostEnt == NULL) { } //获取IP

LPSTR lpAddr = lpHostEnt->h_addr_list[0]; if (lpAddr) { }

//创建套接字

//SOCKET servsock, clisock; SOCKET servsock; printf(\);

servsock = socket(AF_INET, SOCK_DGRAM, 0);//数据报套接字 int servport = 5555; int iSockErr = 0; //定义服务器地址结构 sockaddr_in udpaddr, cliaddr; memset(&udpaddr, 0, sizeof(udpaddr)); memset(&cliaddr, 0, sizeof(cliaddr)); int clilen = sizeof(cliaddr); udpaddr.sin_family = AF_INET;

struct in_addr inAddr;

memmove(&inAddr, lpAddr, 4); //转换为标准格式

IPaddress = inet_ntoa(inAddr);//将一个32位数字表示的IP地址转换成点分十进制IP地址字符串 if (sizeof(IPaddress) == 0) else

printf(\, IPaddress); printf(\); //产生错误

printf(\); return -1;

《数据库技术 》实验报告 授课教师:张国富 苏兆品 zgf@hfut.edu.cn

udpaddr.sin_port = htons(servport);

//将一个点分十进制IP地址字符串转换成32位数字表示的IP地址

udpaddr.sin_addr.s_addr = inet_addr(IPaddress);//\ //绑定套接字到服务器地址结构 printf(\);

iSockErr = bind(servsock, (sockaddr *)&udpaddr, sizeof(udpaddr)); if (iSockErr == SOCKET_ERROR) { }

//函数调用成功,进行其他处理 char buff[256] = \;

char buffer[MAX_LENGTH] = \; int len = 0; //接收欢迎词

memset(buffer, 0, sizeof(buffer)); FILE *fp = NULL; errno_t err;

err = fopen_s(&fp, \七里香.mp3\, \); int i = 0; while (1) {

len = recvfrom(servsock, buffer, sizeof(buffer), 0, (struct sockaddr*)&cliaddr, &clilen); if (len == SOCKET_ERROR) { }

else if (len == 0) { }

buffer[len] = 0;

printf(\, i++, len);

printf(\); break;

printf(\); break;

printf(\, WSAGetLastError());//根据不同的错误类型进行不同的处理 exit(-3);

《数据库技术 》实验报告 授课教师:张国富 苏兆品 zgf@hfut.edu.cn

}

return 0; getchar(); } fclose(fp);

//shutdown(clisock, 2); //

closesocket(clisock); shutdown(servsock, 2); closesocket(servsock); WSACleanup();

Sleep(8);

//printf(\

sendto(servsock, buff, sizeof(buff), 0, (struct sockaddr*)&cliaddr, clilen);

fwrite(buffer, 1, len, fp);

(3)简单的代码移植后接收端是否能正确接收?如果不能请分析原因,并尝试调整发送端读取数据的大小和延迟时间,以及接收端缓冲区的大小来解决数据丢包问题。给出参数调整的理由。

《数据库技术 》实验报告 授课教师:张国富 苏兆品 zgf@hfut.edu.cn

答: 简单的代码移植可能不能正确接受,因为会出现丢包现象。丢包现象在UDP中是很常见的现象。在UDP文件传输中,文件将从client 端发向server端。与TCP不同的是,UDP不需要链接,可以直接传输,但是稳定性不好,容易丢包。调整client端中Sleep(10)的大小来解决这

个问题,使client的延迟时间大于server的延迟时间,例如server的sleep(8)。

本文来源:https://www.bwwdw.com/article/gjoh.html

Top