如何应用TCP IP 的套接字开发网络通信应用程序.docx_第1页
如何应用TCP IP 的套接字开发网络通信应用程序.docx_第2页
如何应用TCP IP 的套接字开发网络通信应用程序.docx_第3页
如何应用TCP IP 的套接字开发网络通信应用程序.docx_第4页
如何应用TCP IP 的套接字开发网络通信应用程序.docx_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

如 何 应 用TCP/IP 的 套 接 字 开 发 网 络 通 信 应 用 程 序 进 入 九 十 年 代 后, 随 着计 算 机 和 网 络 技 术 的 发 展, 很 多 数 据 处 理 系 统 都 采 用开 放 系 统 结 构 的 客 户 机/ 服 务 器 网 络 模 式, 即 客 户 机提 出 任 务 请 求, 通 过 网 络 发 送 给 服 务 器, 由 服 务 器 做相 应 处 理, 执 行 被 请 求 的 任 务, 然 后 将 结 果 返 回 给 客户 机。 例 如: 银 行ATM 的 前 置 机 和 数 据 处 理 的 主 机 之 间即 构 成 客 户 机/ 服 务 器 网 络 模 式; 电 话 银 行 的 前 置 机和 银 行 数 据 处 理 机 之 间 也 构 成 这 种 网 络 模 式 结 构 等。这 样, 如 何 在 前 置 机 和 数 据 主 机 之 间 进 行 信 息 交 换,即 进 程 网 络 通 信, 就 成 为 实 现 这 种 网 络 模 式 的 基 础。而TCP/IP 的 套 接 字 技 术 是 解 这 一 问 题 的 有 力 工 具。 它 从提 出 时 就 一 直 发 挥 着 愈 来 愈 重 要 的 作 用, 并 已 成 为UNIX 操 作 系 统 下TCP/IP 网 络 编 程 标 准; 甚 至WINDOW、JAVA 都 配 有 它的 通 用 接 口。 有 了 这 个 强 有 力 的 工 具, 我 们 可 以 实 现异 种 机、 异 种 操 作 系 统 应 用 程 序 间 的 相 互 连 接 和 通信。 套 接 字(sockets) 是 支 持TCP/IP 协 议 的 网 络 通 信 的 基 本 操 作 单 元。 可 以 将 套 接 字 看 作不 同 主 机 间 的 进 程 进 行 双 向 通 信 的 端 点。 它 构 成 了 在单 个 主 机 内 及 整 个 网 际 间 的 编 程 界 面。 一 般 来 说, 跨机 应 用 进 程 之 间 要 在 网 络 环 境 下 进 行 通 信, 必 须 要 在网 络 的 每 一 端 都 要 建 立 一 个 套 接 字, 两 个 套 接 字 之 间是 可 以 建 立 连 接 的, 也 是 可 以 无 连 接 的, 并 通 过 对 套接 字 的“ 读”、“ 写” 操 作 实 现 网 络 通 信 功 能。 类 似 于UNIX 系 统 中 的I/O 概 念, 像 文 件 那 样 有 打 开、 读、 写、 关 闭 的方 式。 根 据 传 输 数 据 类 型 的 不 同, 套 按 字 可 分 为 面 向连 接 的 数 据 套 接 字(stream sockets) 和 无 连 接 的 数 据 报 套接 字(datagram sockets) 两 种 类 型。 1、 字 节 流 套 接 字 字 节 流 不 按 记 录 定 界,在TCP/IP 协 议 簇 中 对 应TCP 协 议, 即 传 输 控 制 协 议(Transmition Control Protocol)。 它 是 一 个 提 供 给 用 户 进 程 可 靠 的 全 双 工的 面 向 连 接 的 协 议, 大 多 数INTERNET 应 用 程 序 如ftp、telnet 使用TCP 协 议。 通 信 端 点 使 用TCP 对 应 的INTERNET 地 址 互 相 连接, 可 保 证 按 正 确 的 顺 序 以 及 单 一 和 可 靠 的 地 址 传 输数 据。 由 于 它 是 字 节 流, 所 以 包 长 包 没 有 限 制, 信 包传 输 也 不 重 复, 因 而 是 一 种 常 用 的 套 接 字 类 型。 2、 数 据 报 套 接 字 数 据 报 对 应 记 录 型 数 据流, 在TCP/IP 协 议 簇 中 对 应UDP 协 议, 即 用 户 数 据 报 协 议(User Datagram Protocol)。 利 用 数 据 报 服 务 可 实 现 一 些 简 单 的 网络 服 务, 如 网 点 检 测 程 序PING。 由 于 不 建 立 连 接, 数 据报 协 议 比 连 接 协 议 快。 但 不 能 保 证 所 有 数 据 都 准 确 有序 地 到 达 目 的 地。 不 保 证 顺 序 性、 可 靠 性 和 无 重 复性。 它 是 无 连 接 的 服 务, 以 独 立 的 信 包 进 行 传 输, 通信 端 点 使 用UDP 对 应 的INTERNET 地 址。 双 方 不 需 互 连, 按 固定 的 最 大 长 度 进 行 传 输, 因 而 适 用 于 单 个 报 文 传 输,或 较 小 文 件 的 传 输。套 接 字 的 编 程 要 点 及 和 过 程 不 论 何 种 套 接 字 编 程,均 采 用 客 户 机/ 服 务 器 方 式, 其 运 作 过 程 基 本 类 似, 限于 篇 幅, 这 里 仅 介 绍 字 节 流 套 接 字。 字 节 流 套 按 字 的服 务 进 程 和 客 户 进 程, 在 通 信 前 必 须 创 建 各 自 的 套 接字 以 建 立 连 接, 然 后 对 相 应 的 套 接 字 进 行“ 读”、“ 写” 操 作, 实 现 信 息 的 交 换。 服 务 器 进 程 创 建 套 接 字。 服 务 进 程 总 是 先 于 客 户 进程 启 动, 服 务 进 程 首 先 调 用socket() 函 数 创 建 自 已 端 的 一个 字 节 流 套 接 字, 并 提 供 三 个 参 数: 网 络 地 址 类 型,一 般 取AF_INEF(Adress family InterNET); 套 接 字 类 型, 这 里 取SOCK_STREAM;网 络 协 议, 缺 省 为TCP/IP 协 议, 对 应 参 数 为0。给 套 接 字 地 址 变 量 赋 初 值。 在 生 成 套 接 字 后, 要 用服 务 器 的 地 址 先 对sockaddr_in 结 构 变 量 赋 初 值。Sockaddr_in 在/usr/include/netinet/in.h 中 有 定 义, 它 只 适 用 于INTERNET 地 址 类 型, 含 有INTERNET 套 接字 地 址 类 型、IP 端 口 号、IP 地 址 等 信 息。 地 址 类 型 可 取定 为AF_INET,IP 地 址 对 服 务 器 可 取 任 意 合 法 地 址INADDR_ANY。IP 端 口 号 可 由 用 户 设 定, 但 要 注 意 主 机 字 节 顺 序 向 网 络字 节 顺 序 的 转 换。给 套 接 字 命 名。 由socket() 函 数 创 建 的 套 接 字 是 没 有 名字 的。 所 谓 命 名, 就 是 用bind() 函 数 将 服 务 器 地 址 捆 绑到 创 建 的 套 接 字 上。服 务 器 进 程 准 备 接 受 来 自 客 户 机 的 连 接 请 求。 首 先调 用listen() 函 数, 让 服 务 器 进 程 进 入 监 听 状 态; 然 后 调用accept() 函 数, 准 备 接 受 客 户 机 的 连 接 信 号。 无 连 接 请求 时, 服 务 进 程 被 阻 塞。客 户 进 程 调 用socket() 函 数 创 建 已 端 的 套 接 字。给 客 户 端 的sockaddr_in 结 构 体 变 量 赋 值。 地 址 类 型 仍 可取AF_INET, 端 口 号 和 服 务 器 方 的 端 口 号 相 同, 欲 连 服 务器 的 地 址 通 过 调 用inet_addr() 转 换 得 到。 也 可 通 过gethostbyname() 函 数 将 名 字 转 换 为 指 向hostent 结 构 变 量 的 指 针, 再 将hostent 结 构 变 量 的 地 址 成 员 用bcopy() 复 制 到sockaddr_in 结 构 变 量上。客 户 方 调 用connect() 函 数 向 服 务 进 程 发 出 连 接 请 求。当 连 接 请 求 到 来 后, 被 阻 塞 服 务 进 程 的accpet() 函 数 生成 一 个 新 的 字 节 流 套 接 字, 并 返 回 客 户 机 的sockaddr_in 结构 变 量, 从 而 在 服 务 器 应 用 程 序 中 用 新 的 被 赋 予 客 户机 地 址 的 套 接 字 同 客 户 进 程 进 行 连 接, 然 后 向 客 户 方返 回 接 受 信 号。一 旦 客 户 机 的 套 接 字 收 到 来 自 服 务 器 的 接 受 信 号,则 表 示 客 户 机 与 服 务 器 双 方 已 实 现 连 接。 任 一 方 均 可向 对 方 发 送, 也 可 接 收 对 方 发 来 的 数 据。 这 既 可 通 过send()、recv() 函 数 来 实 现。 也 可 通 过read()、write() 函 数 来 交 换 数 据。服 务 进 程 和 客 户 进 程 可 通 过 调 用shutdown() 和colse() 关 闭 套接 字 上 的 所 有 发 送 和 接 收 操 作, 撤 销 套 接 字 并 中 断 连接。 上 述 所 有 系 统 函 数 均包 括 在libsocket.a 系 统 库 中,IBM PC(UNIX) 操 作 系 统 编 译 时 需加-llibsocket 链 接。IBM RS/6000(AIX) 操 作 系 统 统 编 译 时 无 需 此 参数。 整 个 运 作 过 程 可 用 图表 示 如 下:编 程 示 例 本 文 给 出 一 个 运 用 字节 流 套 接 字, 在TCP/IP 网 络 上 实 现 客 户 机/ 服 务 器 方 式 进程 通 信 的 实 例, 该 程 序 在IBM RS/6000 小 型 机 和IBM PC 586 微 机上 调 试 通 过。 它 主 要 模 拟 根 据 帐 号 查 询 余 额 的 过 程,客 户 机 是 一 台 电 话 银 行 的 前 置 机(IBM PC), 服 务 器 是 银行 数 据 处 理 主 机(IBM RS/6000), 包 括 三 方 面: 客 户 机 从 标 准 输 入 读 入 帐 号, 并 将 该 帐 号 发 送 给 服务 器。服 务 器 接 收 该 帐 号 后, 进 行 判 断 是 否 有 此 帐 号 的 数据, 并 将 结 果 返 回 给 客 户 机。客 户 机 接 收 返 回 的 信 息, 并 将 结 果 输 出 在 标 准 输 出上。 服 务 进 程 需 先 于 客 户进 程 启 动。 客 户 进 程 启 动 时 要 携 带 服 务 器 的IP 地 址,如:clientpros 在UNIX 操 作 系 统 下 可 用Doscp 命 名 拷 入 硬 盘; 编 译 时 用: cc hxserver.c -lsocket -0 server cc hxclient.c -lsocket -0 client 在AIX 操 作 系 统 下 可 用Dosread 命 名 拷 入 硬 盘, 编 译 时 用: cc hxserver.c -0 server cc hxclient.c -0 client/*服务器端程序:hxserver.c*/#include #include #include #include #include tcpipop.cmain()int newsockfd, sockfd;int clilen;struct sockaddr_in cli_addr, serv_addr;char info100;int infolen;int rc;if (sockfd = socket(AF_INET, SOCK_STREAM, 0) 0)/*创建TCP协议的字节流*/ fprintf(stderr, Socket failed !n); return(-1); bzero(char *)&serv_addr, sizeof(serv_addr);/*服务器地址清0*/ serv_addr.sin_family=AF_INET;/*网络类型使用ARPA internet地址*/ serv_addr.sin_addr.s_addr=htonl(INADDR_ANY); /*IP地址取公认的任意合法地址*/ serv_addr.sin_port=htons(1234); /*设定IP端口号, 并将主机字节顺序转换为网络字节顺序*/ if ( bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr) 0 ) /*将服务器地址信息捆绑到创建的套接字上*/ fprintf(stderr, Bind failed !n); return(-1); if ( listen(sockfd, 5) 0 )/*建立长度为5的监听队列从套接字上收听连接请求*/ fprintf(stderr, Listen failed !n); return(-1); fprintf(stderr, blocked here.n); clilen=sizeof(cli_addr); /*阻塞至客户方有连接请求到来*/ newsockfd=accept(sockfd, (struct sockaddr *)&cli_addr, &clilen); /*有连接请求时, 返回被赋予客户机地址的新套接字, 连接已建立*/ fprintf(stderr, connected now!n); if ( newsockfd 0 ) fprintf(stderr, Accept failed!n); return(-1); shutdown(sockfd, 2); close(sockfd); memset(info,0,sizeof(info); infolen=6; if (rc=TCPRECEIVE(newsockfd, info, infolen)= 1)/*接受客户机发来的信息*/ fprintf(stderr, TCPRecv failed !n); if (!memcmp(info,123456,6) /*返回帐号为123456的帐户信息*/ printf(received account no is %6.6sn,info); sprintf(info,%6.6s|%8.8s|%10.2lf,info,zhang li,123.456); else /*否则, 返回000000表示无此帐户*/ printf(no such account no %6.6sn,info); sprintf(info,%6.6s|%8.8s|%lf,000000,0.0); infolen=sizeof(info); if (rc=TCPSEND(newsockfd, info, infolen) )= 1) /*向客户机发送该帐户信息*/ fprintf(stderr, TCPSend failed !n); shutdown(newsockfd, 2); close(newsockfd); /*客户端程序:hxclient.c*/ #include #include #include #include #include tcpipop.ctypedef structchar accno7;char name9;double amt; data_type;/* 帐户数据结构 */main(argc,argv)int argc;char * argv; int I=0; int sockfd; struct sockaddr_in serv_addr;/*存服务器方的地址*/char info100;int infolen;data_type data;int rc;if (argc!=2)fprintf(stderr,client ipaddressn);exit(-1);/*参数是服务器的IP地址*/ for ( ; I10; I+ )/*最多连接10次*/ bzero(char *)&serv_addr, sizeof(serv_addr); /*服务器地址变量清0*/ serv_addr.sin_family=AF_INET; /*网络地址类型使用ARPA internet 地址*/ serv_addr.sin_addr.s_addr=inet_addr(argv1); /*服务器IP地址转换为长整型IP地址, 并赋予地址结构变量*/ serv_addr.sin_port=htons(1234); /*与服务器相同的IP端口号, 经主机字节顺序到网络字节顺序的转换*/ if (sockfd=socket(AF_INET, SOCK_STREAM, 0) = 0)/*与服务进程建立连接*/break;shutdown(sockfd, 2);close(sockfd); if ( I = 10 ) exit(-1); /*此时连接已建立, 可通过对套接字的读写实现通信*/memset(&data,0,sizeof(data);printf(enter account no:);scanf(%s,data.accno); /*输入要检索的帐号*/infolen=sizeof(data.accno);bcopy(&data.accno,info,infolen); if ( (rc=TCPSEND(sockfd, info, infolen) = -1 )

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论