实验六_tcp、udp通信程序设计实验

上传人:j7****6 文档编号:61611155 上传时间:2018-12-06 格式:PPT 页数:39 大小:1.44MB
返回 下载 相关 举报
实验六_tcp、udp通信程序设计实验_第1页
第1页 / 共39页
实验六_tcp、udp通信程序设计实验_第2页
第2页 / 共39页
实验六_tcp、udp通信程序设计实验_第3页
第3页 / 共39页
实验六_tcp、udp通信程序设计实验_第4页
第4页 / 共39页
实验六_tcp、udp通信程序设计实验_第5页
第5页 / 共39页
点击查看更多>>
资源描述

《实验六_tcp、udp通信程序设计实验》由会员分享,可在线阅读,更多相关《实验六_tcp、udp通信程序设计实验(39页珍藏版)》请在金锄头文库上搜索。

1、实验六 TCP、UDP通信程序设计实验,2,客户1,客户2,服务器,请求,应答,请求,应答,通信程序基础:客户端和服务器,3,IPv4, IPv6,Ethernet Adapter,App1,App2,port A,port B,TCP,UDP,通信程序基础:分层,4,TCP通信实验cont1,5,http:/ 得到ip地址 建立tcp连接: 构造http数据包,向tcp请求 构造tcp数据包,承载http包 构造ip数据包 得到mac地址 构造数据帧,通信程序基础:实例,6,7,Socket介绍(1),什么是socket? 先看文件操作的例子: 通过open函数得到一个文件的文件描述符;然后

2、对这个描述符进行读写,得到一个整数来标识这个文件,称为file descriptor,得到一个整数来标识这个文件,把用来标识这个文件整数看作是这个入口的标识,把用来标识这个文件的整数看作是这两入口的标识,8,Socket介绍(2),socket,socket,Socket descriptor,用类似于open的函数得到一个socket 描述符,然后对这个描述符进行读写操作,9,从网络整体来看,socket是不同主机上应用程序之间的一个虚拟的接口,具有跨平台特性。 从程序员角度来看,它是应用程序和网络设备的一个接口,特殊的I/O 从操作系统看,它是一种资源。如同handle用来描述window

3、s中的窗口等资源,socket用socket descriptor来标识。,Socket介绍(3),10,字节流套接口(Stream Sockets) 面向连接的,位于TCP之上 数据报套接口(Datagram Sockets) 无连接的,位于UDP之上 原始套接口(Raw Sockets) 直接发送和处理IP包:例如ping,Socket介绍(4),11,Socket的起源 最初在70年代由加州大学Berkeley分校开发,其目的是为BSD(Berkeley Software Distribution) UNIX 4.1版操作系统提供网络通信接口。 Socket在各种平台下的发展 随着Ber

4、keley Sockets的广泛应用,九十年代初,Sun、MS等公司共同制定了适应dos和win平台的windows sockets的规范(WinSock) Sun Microsystems为Java也制定了网络通信的API Linux下的socket继承了BSD sockets的风格,并有所改动 不同的网络有不同的套接口 CCITT X.25套接口 Berkeley 套接口,Socket介绍(5),12,现在开始具体介绍socket编程。 由前面的叙述可以看出,我们要进行通信就要得到对应的socket descriptor,一旦得到了,对它进行读写操作就可以了,例如 int read( in

5、t fd, char *buf, int len); int write(int fd, char *buf, int len); 在与另一台计算机通信之前要知道对方的什么信息? IP地址或者域名 端口(用来区分不同的应用),Socket介绍(6),13,Socket用下面的结构体来描述一个IP地址socket.h 结构中sa_family为套接口的协议族地址类型,例如对于通常的TCP/IP协议(IPv4),它的值是AF_INET; sa_data中存储着具体的协议地址,不同的协议族有不同的地址格式。 sa_data的存储内容往往是包含地址和端口信息,而仅使用一个变量,使用起来不太方便定义新的

6、Socket地址结构,Socket介绍(7),struct sockaddr unsigned short sa_family; /* 地址家族2字节*/ char sa_data14; /*14字节协议地址*/ ;,14,新版的socket地址的定义 最后的那个元素是填充的空白信息, 这样就保持整个结构与sockaddr结构的长度相同,Socket介绍(8),struct sockaddr_in short int sin_family; /* 通信类型2字节 */ unsigned short int sin_port; /* 端口, 2字节*/ struct in_addr sin_ad

7、dr; /* Internet 地址, 4字节*/ unsigned char sin_zero8; ,注意理解指针和类型强制转换,15,Socket介绍(9),struct in_addr unsigned long s_addr; ;,图中的紫色部分就是端口和IP地址。这两个域必须是网络字节顺序 Network Byte Order,struct sockaddr_in short int sin_family; /* 通信类型2字节 */ unsigned short int sin_port; /* 端口, 2字节*/ struct in_addr sin_addr; /* Inter

8、net 地址, 4字节*/ unsigned char sin_zero8; ,16,struct in_addr union struct unsigned char s_b1; unsigned char s_b2; unsigned char s_b3; unsigned char s_b4; S_un_b; struct unsigned short s_w1; unsigned short s_w2; S_un_w; unsigned long S_addr; S_un; ;,17,sockaddr只是一个抽象的概况形式,并不实用 sockaddr_in更加结合了TCP/IP协议族的

9、特点,易于使用,所以编程中常使用这个结构。 但是:socket本身所封装的API都是支持sockaddr结构的,所以填充sockaddr_in结构需要强制转换成sockaddr结构,方可作为参数被socket的标准函数所使用。例如: int connect( int sockfd, struct sockaddr * servaddr, unsigned int addrlen),Socket介绍(10),18,字节顺序 主机字节顺序(Host Byte Order) 低位在前,高位在后(little-endian) 基于Intel芯片的机器采取这种存储方式 网络字节顺序(Network By

10、te Order) 高位在前,低位在后(big-endian) Sockaddr_in的变量成员(端口和地址)都必须使用网络字节顺序,字节顺序,19,例如端口34567的16进制表示是0x8707。如果定义变量unsigned short sin_port = 34567,0x11111111,0x11111112,主机字节序,.68 1f e3 34 87 07 36.,网络字节序,以字节为最小单位,但是计算机对内存的读取是双字节的,如果是ip地址202.38.75.11的16进制表示。如果定义变量unsigned long s_addr = 0xCA264B0B,0x22222222,0x

11、22222225,0B,4B,26,CA,.68 1f CA 26 4B 0B 12.,20,字节顺序,转换字节顺序的函数(in.h),uint16_t htons(uint16_t); uint16_t ntohs(uint_16_t); uint32_t htonl(uint32_t); uint32_t ntohl(uint32_t);,h : host n : network s : short (16bit) l : long (32bit),例如:定义struct sockaddr_in sh; unsigned short port = 12345; sh.sin_port =

12、htons(port);,htons和ntohs的实现是一样的;htonl和ntohl一样,21,前面提到的几个函数对于IP地址的转换仍然不方便,因为首先得得到ip地址的数值表示,而我们习惯于用带点的字符串来表示,如“202.38.75.11” 因此希望有函数能处理这样的请求: 给一个字符串如“202.38.75.11”能返回相应的网络字节序的unsigned long值 给一个unsigned long的值能返回一个字符串,字节顺序,22,inet_aton int inet_aton(const char *cp, struct in_addr *inp); 例如将“192.168.0.1

13、0”转化为0xC0A8000A inet_addr unsigned long inet_addr(const char *cp); 功能同上,但不能处理广播地址 inet_ntoa char * inet_ntoa(struct in_addr in); 例如将0xC0A8000A转化为“192.168.3.10”,23,TCP通信实验,注意bind和listen,socket(),bind(),listen(),accept(),write(),read(),read(),TCP Server,close(),socket(),TCP Client,connect(),write(),re

14、ad(),close(),建立连接,客户请求,服务器响应,结束连接,24,基本套接口函数(1)- socket(),int fd; /* socket descriptor */ if (fd = socket(AF_INET, SOCK_STREAM, 0) 0) fprintf(stderr,“socket creating errorn”); exit(1); /*注:在TCP或UDP编程的时候,protocol都取0*/,#include int socket(int domain, int type, int protocol); 创建socket 返回:非负整数描述符表示成功,-1

15、表示出错 domain一般设为AF_INET,protocol一般设为0,25,基本套接口函数(2)- connect(),#include int connect(int sockfd, struct sockaddr * servaddr, unsigned int addrlen); 返回:0表示成功,-1表示出错,connect()由客户使用, 旨在和服务器建立一个连接。sockfd是函数socket()返回的套接口描述符, servaddr表示远程服务器的套接口, addrlen表示套接口地址的长度 注意:之前要先调用socket()创建套接口,26,TCP通信- 客户端例子,int

16、 fd; /* 套接口描述符 */ struct sockaddr_in srv; /* 套接口地址结构 */ fd = socket(AF_INET, SOCK_STREAM, 0); /* connect: AF_INET表示使用Internet地址族 */ srv.sin_family = AF_INET; /* connect: 目标是连向服务器的 8000 号端口 */ srv.sin_port = htons(8000); /* connect: 目标服务器的 IP Address 是 “202.38.75.11” */ srv.sin_addr.s_addr = inet_addr(“202.38.75.11”); if(connect(

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 社会民生

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号