UDP及TCP通信程序的设计与实现实验报告.docx
- 文档编号:18363583
- 上传时间:2023-08-16
- 格式:DOCX
- 页数:22
- 大小:223.50KB
UDP及TCP通信程序的设计与实现实验报告.docx
《UDP及TCP通信程序的设计与实现实验报告.docx》由会员分享,可在线阅读,更多相关《UDP及TCP通信程序的设计与实现实验报告.docx(22页珍藏版)》请在冰点文库上搜索。
UDP及TCP通信程序的设计与实现实验报告
实验报告
课 程计算机网络(双语)(课程设计)
实验名称UDP及TCP通信程序的设计与实现
专业班级
姓 名
学 号
2013年5月30日
实验环境ﻩ2
程序的逻辑框图ﻩ2
程序源代码(数据结构的描述、核心算法)ﻩ4
1.TCP通信程序源代码4
2.TCP通信程序数据结构的描述ﻩ7
3.TCP通信程序的核心算法ﻩ7
4.UDP通信程序源代码8
5.UDP通信程序数据结构的描述11
6.UDP通信程序的核心算法12
实验数据、结果分析13
TCP通信程序实验结果分析ﻩ13
UDP通信程序实验结果分析14
总结16
实验目的和内容
实验目的
掌握win32平台下,使用winsock API来实现UDP通信程序和TCP通信程序。
实验内容
1.实现控制台模式下,在单机上基于UDP的聊天程序;
2.实现控制台模式下,在单机上基于TCP的聊天程序;
3.上述两个程序,最简单的实现方式是:
一方发送、另一方接收、交替进行;
4.提交上述2个程序的源程序,程序代码有充分的注释,并填写实验报告,实验报告的主要内容为说明程序设计的思路,程序代码的流程。
实验环境
在win7系统下,visual studio 2008环境下的win32平台下
程序的逻辑框图
UDP通信程序的逻辑框图:
TCP通信程序的逻辑框图:
程序源代码(数据结构的描述、核心算法)
1.TCP通信程序源代码
Client端:
#include "stdafx.h"
#include<stdlib.h>
#include<stdio.h>
#include <string.h>
#include
//初始化函数,初始化版本号
intInitSock(BYTEminorVer= 2,BYTE majorVer=2)
{
ﻩWSADATAwsaData;
WORDsockVersion=MAKEWORD(minorVer, majorVer);
if(WSAStartup(sockVersion, &wsaData)!
= 0)
exit(0);
ﻩreturn1;
}
int main()
{
charrbuf[256];
ﻩcharszText[256];
ﻩInitSock();
//创建socket,第一个参数表示用IP协议,第二个参数表示用TCP传输,第三个不大清楚
ﻩSOCKET sListen=socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
ﻩ
ﻩ//判断socket是否创建成功
if(sListen==INVALID_SOCKET)
ﻩ{
ﻩprintf("Failedsocket()\n");
ﻩﻩreturn0;
ﻩ}
ﻩ//用于存储IP地址和端口号的变量
sockaddr_insin;
sin.sin_family=AF_INET;//IP协议
sin.sin_port= htons(4567);ﻩ//端口号
sin.sin_addr.S_un.S_addr=INADDR_ANY; //接收任何IP的连接
//绑定函数,将socket与 IP地址和端口绑定在一块
if(bind(sListen,(LPSOCKADDR)&sin,sizeof(sin)) == SOCKET_ERROR)
{
ﻩﻩprintf("Failedbind()\n");
ﻩreturn0;
ﻩ}
//开始监听,第二个参数表示最大连接数
if(listen(sListen, 2) ==SOCKET_ERROR)
{
printf("Failedlisten()\n");
ﻩﻩreturn0;
ﻩ}
ﻩ//定义一个新的变量
sockaddr_inremoteAddr;
intnAddrLen =sizeof(remoteAddr);
ﻩ//用于存储连接客户端的socket
SOCKETsClient;
//accept函数会阻塞,直到等到有socket连接服务器为止,才继续往后执行,并将客户端的IP和端口号存在remoteAddr中
ﻩsClient= accept(sListen, (SOCKADDR*)&remoteAddr,&nAddrLen);
printf("接收到一个连接%s\r\n",inet_ntoa(remoteAddr.sin_addr));
ﻩwhile(TRUE)
ﻩ{
ﻩﻩif(sClient==INVALID_SOCKET)
ﻩ{
ﻩﻩprintf("Failedaccept()");
ﻩﻩcontinue;
}
ﻩﻩprintf("send:
");
ﻩscanf("%s",szText);
ﻩﻩ//发送函数,往sClient这个socket中发送szText
send(sClient,szText,strlen(szText),0);
//recv为阻塞函数,等待sClient中传来数据
int nRecv=recv(sClient,rbuf,256,0);
ﻩif(nRecv>0)
ﻩ{
ﻩrbuf[nRecv] ='\0';
ﻩﻩﻩprintf("receive:
%s\n",rbuf);
}
}
closesocket(sClient);
ﻩclosesocket(sListen);
ﻩWSACleanup();
return0;
}
Server端:
#include"stdafx.h"
#include
#include
#include <string.h>
#include
//初始化函数,初始化版本号
intInitSock(BYTEminorVer= 2,BYTEmajorVer= 2)
{
ﻩWSADATAwsaData;
ﻩWORD sockVersion =MAKEWORD(minorVer,majorVer);
ﻩif(WSAStartup(sockVersion,&wsaData)!
=0)
ﻩexit(0);
ﻩreturn1;
}
intmain()
{
ﻩInitSock();
//创建socket,第一个参数表示用IP协议,第二个参数表示用TCP传输,第三个不大清楚
ﻩSOCKETs=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(s==INVALID_SOCKET)
{
printf(" Failedsocket()\n");
return0;
ﻩ}
//用于存储IP地址和端口号的变量
ﻩsockaddr_inservAddr;
servAddr.sin_family= AF_INET;
servAddr.sin_port=htons(4567);ﻩ//要连接的端口号
servAddr.sin_addr.S_un.S_addr= inet_addr("127.0.0.1");//要连接的IP地址
//连接函数,是一个阻塞类型的函数,用s这个socket与服务器地址的某个端口连接,之后往s这个socket中写数据,服务器就能收到
ﻩif(connect(s,(sockaddr*)&servAddr,sizeof(servAddr))==-1)
{
ﻩﻩprintf("Failedconnect()\n");
ﻩreturn 0;
}
char buff[256];
ﻩcharszText[256];
ﻩwhile(true){
//接收函数,是一个阻塞类型的函数,等待s这个socket中传来数据,256表示接收的最大字符数
ﻩintnRecv= recv(s, buff,256,0);
ﻩif(nRecv > 0)
ﻩ{
ﻩﻩbuff[nRecv]='\0';
ﻩprintf("receive:
%s\n",buff);
ﻩ}
printf("send:
");
ﻩscanf("%s",szText);
ﻩ//发送函数,往s这个socket中发送szText这个字符串
ﻩsend(s,szText, strlen(szText), 0);
ﻩ}
closesocket(s);
ﻩWSACleanup();
return0;
}
2.TCP通信程序数据结构的描述
(1)客户端及服务器都含有存储IP地址及端口号的数据结构,sockaddr_in remoteAddr;和servAddr
(2)用于存储连接客户端的socket:
SOCKETsClient;和用于存储连接服务器的socket:
SOCKETs
3.TCP通信程序的核心算法
服务器首先启动,通过调用socket()建立一个套接口,然后bind( )将该套接口和本地地址(IP地址和端口)联系在一起,再listen()使套接口做好侦听的准备,并规定它的请求队列的长度, 之后就调用accept()来接收连接,并获得客户机的地址信息;客户在建立套接口后就可调用connect( )和服务器建立连接; 连接一旦建立,客户机和服务器之间就可以通过调用:
send()和recv()(或read()和write( ))来发送和接收数据;最后,待数据传送结束后,双方调用closesocket()关闭套接口。
4.UDP通信程序源代码
Client端:
#include "stdafx.h"
#include<winsock.h>
#include
#include <stdio.h>
//在同一主机的不同端口上分别运行服务器程序和客户端程序
WORD RPort=6666;//远程端口RemotePort
char RIP[16]="127.0.0.1";//远程IP地址RemoteIPAddr
WORD LPort=7777;//本地端口LocalPort
charLIP[16]="127.0.0.1";//本地IP地址LocalIPAddr
SOCKETS;//套接口SOCKET
struct sockaddr_inrAddr;//远程参数,remoteAddr
structsockaddr_inlAddr; //本地参数,localAddr
WSADATAWD;//Winsock DLL信息
int r;//result;
//-----------------------------------------------
voidShowInfo(char *info){
puts(info);
ﻩexit
(1);
}
//-----------------------------------------------
void SetsockAddr(structsockaddr_in*A,WORDPort,char*IP){
A->sin_family= AF_INET;//TCP/IP协议
ﻩA->sin_port= htons(Port);//端口
A->sin_addr.s_addr =inet_addr(IP); //IP地址
}
//------------------------------------------------
voidmain(){
WORDv;//wVersionRequested;
ﻩ//--- --- -- -StartupWinsocket- ------ -
v=0x0101; //0x0101forv1.1,0x0002 forv2.0
r = WSAStartup(v,(LPWSADATA)&WD);
if(r!
= 0)
ﻩShowInfo("Start_Error");
ﻩ//--- - -- - --CreateWinsocket--- -- ---
S =socket(AF_INET,SOCK_DGRAM,0);//创建套接字
if(S ==-1)
ﻩShowInfo("socket_Create_Error");
int l=sizeof(rAddr);
ﻩcharMsg[80];
puts("Type exit thenQuit Program!
");
SetsockAddr(&lAddr,LPort,LIP);//初始化变量lAddr
r=bind(S,(structsockaddrfar *)&lAddr,sizeof(lAddr));
if(r==-1)
ﻩShowInfo("bind_Error");
ﻩSetsockAddr(&rAddr, RPort,RIP);
ﻩdo{
//--- -- - - - -Send Mess--- -----
ﻩputs("Send:
");
ﻩgets(Msg);
ﻩif(!
strcmp(Msg,"exit"))//
ﻩbreak;
ﻩﻩr= sendto(S,Msg,strlen(Msg), 0,(structsockaddrfar*)&rAddr,l);//通过套接字向接收端发送信息
if(r == -1)
ﻩﻩShowInfo("Send_Error");
ﻩ//-- -- ---- -RecieveMess - -- -----
ﻩputs("Sendok!
WaitingRecieve...");
//r= recv(S,Msg,80,0);
r= recvfrom(S,Msg,80,0,(structsockaddrfar*)&rAddr,&l);//
//发送套接口的主机地址信息存放在rAddr中
if(r ==-1)
ﻩShowInfo("Recieve_Error");
ﻩMsg[r]=0;
puts(Msg);
ﻩputs("Recieveok!
");
ﻩ}while
(1);
ﻩclosesocket(S);
WSACleanup();
return;
Server端:
#include "stdafx.h"
#include <winsock.h>
#include
#include<stdio.h>
//在同一主机的不同端口上分别运行服务器程序和客户端程序
WORDRPort=7777;//远程端口RemotePort
char RIP[16]="127.0.0.1"; //远程IP地址RemoteIPAddr
WORD LPort =6666; //本地端口LocalPort
charLIP[16]="127.0.0.1";//本地IP地址LocalIPAddr
SOCKETS; //套接口SOCKET
struct sockaddr_inrAddr;//远程参数,remoteAddr
structsockaddr_in lAddr; //本地参数,localAddr
WSADATAWD;//Winsock DLL信息
intr;//result;
//-----------------------------------------------
voidShowInfo(char *info){
puts(info);
exit(1);
}
//-----------------------------------------------
void SetsockAddr(structsockaddr_in *A,WORDPort,char *IP){
A->sin_family =AF_INET; //TCP/IP协议
ﻩA->sin_port= htons(Port);//端口
ﻩA->sin_addr.s_addr=inet_addr(IP); //IP 地址
}
//------------------------------------------------
voidmain(){
ﻩWORDv; //wVersionRequested;
ﻩ//--------- StartupWinsocket--- -----
v=0x0101;//0x0101forv1.1,0x0002forv 2.0
r =WSAStartup(v,(LPWSADATA)&WD);
ﻩif(r!
=0)
ﻩShowInfo("Start_Error");
//--- ------Create Winsocket------ --
S=socket(AF_INET,SOCK_DGRAM, 0);//创建套接字
if(S==-1)
ShowInfo("socket_Create_Error");
ﻩintl=sizeof(rAddr);
charMsg[80];
puts("TypeexitthenQuitProgram!
");
ﻩSetsockAddr(&lAddr,LPort,LIP);//初始化变量lAddr
r= bind(S,(struct sockaddrfar *)&lAddr,sizeof(lAddr));
ﻩif(r==-1)
ﻩShowInfo("bind_Error");
SetsockAddr(&rAddr,RPort,RIP);
do{
ﻩﻩ//-- - - -- ---RecieveMess- - ------
ﻩﻩ//puts("Sendok!
WaitingRecieve...");
ﻩ//r=recv(S,Msg,80,0);
r=recvfrom(S,Msg,80,0,(structsockaddr far *)&lAddr,&l);//发送套接口的主机地址信息存放在rAddr中
ﻩif(r ==-1)
ﻩShowInfo("Recieve_Error");
ﻩﻩMsg[r]=0;
ﻩputs(Msg);
puts("Recieveok!
");
ﻩ//-------- - SendMess--- -----
ﻩputs("Send:
");
ﻩgets(Msg);
ﻩif(!
strcmp(Msg,"exit"))//
ﻩﻩbreak;
ﻩr=sendto(S,Msg,strlen(Msg),0,(structsockaddrfar*)&lAddr,l);//通过套接字向接收端发送信息
if(r==-1)
ﻩShowInfo("Send_Error");
}while
(1);
closesocket(S);
WSACleanup();
ﻩreturn;
}
5.UDP通信程序数据结构的描述
(1)SOCKETS:
服务器套接字
(2)structsockaddr_inrAddr:
远程参数,remoteAddr,存储TCP/IP协议,IP地址及端口号
(3)struct sockaddr_inlAddr:
本地参数,localAddr,存储TCP/IP协议,IP地址及端口号
6.UDP通信程序的核心算法
服务器首先启动,通过调用socket()建立一个套接口,然后bind()将该套接口和本地地址(IP地址和端口)联系在一起,服务器调用recvfrom( )等待接收数据。
客户机通过调用socket()建立一个套接口,然后bind()将该套接口和本地地址(IP地址和端口)联系在一起,客户机调用sendto()向服务器发送数据;
服务器的recvfrom()接收到客户机的数据后,调用sendto()向客户机发送应答数据;
客户机的recvfrom()便接收到了服务器的应答数据;
最后,待数据传送结束后,双方调用closesocket()关闭套接口。
关于程序中调用的库函数的几点说明:
1.对sendto函数的说明
intsendto(
SOCKET s,//源套接口
char*buf,//待发送数据的缓冲区
intbuflen, //缓冲区中数据的长度
intflags,//调用方式标志位,一般取0
structsockaddrFAR *to, //指向目的套接口的主机地址
int tolen//目的套接口主机地址的长度
);
sendto函数主要用于SOCK_DGRAM类型套接口向to参数指定端的套接口发送数据报。
对于SOCK_STREAM类型套接口,to和tolen 参数被忽略;这种情况下sendto() 等价于send()。
2.对recvfrom函数的说明
intrecvfrom(
SOCKETs//接收套接口
char*buf//接收数据的缓冲区
intlen //缓冲区中数据的长度
intflags//调用方式标志位,一般取0
structsockaddrFAR*from// 获取发送套接口的主机地址
intfromlen//发送套接口的主机地址的长度
);
recvfrom函数主要用于从一个套接口接收数据
实验数据、结果分析
TCP通信程序实验结果分析:
当Client端启动时,Server端收到来自Client端的信号,表明双方的连接已经建立,可以互相通讯,从client端发送“hello”,Server端收到来自Client端的“hello”, Server端也可以向client端发送信息。
UDP通信程序实验结果分析:
打开UDP的client端,并打开UDP的server端,发送“hello”给server端,如下图所示:
server端收到信息以后,发送“hi”给client端,client端也能收到信息。
总结
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- UDP TCP 通信 程序 设计 实现 实验 报告