热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SOAP和HTTP关系,以及TCP/IP和SOCKET通讯知识,以及C语言实现socket通讯

SOAP和HTTP关系SOAP:简单对象访问协议是交换数据的一种协议规范,是一种轻量的、简单的、基于XML(标准通用标记语言下的一个子集)

SOAP和HTTP关系

SOAP:简单对象访问协议是交换数据的一种协议规范,是一种轻量的、简单的、基于XML(标准通用标记语言下的一个子集)的协议,它被设计成在WEB上交换结构化的和固化的信息。

构建模块
一条 SOAP 消息就是一个普通的 XML 文档,包含下列元素:
必需的 Envelope 元素,可把此 XML 文档标识为一条 SOAP 消息
可选的 Header 元素,包含头部信息
必需的 Body 元素,包含所有的调用和响应信息
可选的 Fault 元素,提供有关在处理此消息所发生错误的信息
语法规则
这里是一些重要的语法规则:
SOAP 消息必须用 XML 来编码
SOAP 消息必须使用 SOAP Envelope 命名空间
SOAP 消息必须使用 SOAP Encoding 命名空间
SOAP 消息不能包含 DTD 引用
SOAP 消息不能包含 XML 处理指令

HTTP:HTTP协议目的是规定客户端和服务端数据传输的格式和数据交互行为,并不负责数据传输的细节。底层是基于TCP实现的。
常用的请求方法:GET/POST/DELETE/PUT
常见的响应的状态码:200OK/400Bad Request/403Forbidden/404Not Found/500Internal Server Error/

HTTP是一个通信协议,通过网络传输信息。

SOAP
是一个基于XML的协议交换消息,可以使用HTTP来传输这些信息。事实上HTTP是SOAP消息的最常见的传输工具。soap将信息进行XML的序列化后,再用http协议的方式再打包进行传送,传送的方式还是tcp或者udp。

SOAP采用了已经广泛使用的两个协议:HTTP 和XML(标准通用标记语言下的一个子集)。HTTP用于实现 SOAP 的RPC 风格的传输, 而XML 是它的编码模式。
SOAP 通讯协议使用 HTTP 来发送XML 格式的信息。
soap将信息进行XML的序列化后,再用http协议的方式再打包进行传送,传送的方式还是tcp或者udp。
做个比喻就好理解了:tcp 和 udp 都是公路,暂且把tcp认为是一般公路,udp高速公路,soap和http就都是汽车,那么soap和http都可以在tcp和udp上跑。
说soap可以通过http来传送,实际就是说soap是小轿车,http是装轿车的卡车,把soap的信息装到http里面,然后再运输,当然走的道路还是tcp或udp。
说soap可以通过http协议来传输,这句话不太准确,比较准确第说法是:soap信息可以通过http协议包装后通过tcp或udp传输。

TCP相关知识

TCP是面向连接的通信协议,通过三次握手建立连接,通讯完成时要拆除连接,由于TCP是面向连接的所以只能用于端到端的通讯。
TCP提供的是一种可靠的数据流服务,采用“带重传的肯定确认”技术来实现传输的可靠性。TCP还采用一种称为“滑动窗口”的方式进行流量控制,所谓窗口实际表示接收能力,用以限制发送方的发送速度。
如果IP数据包中有已经封好的TCP数据包,那么IP将把它们向‘上’传送到TCP层。TCP将包排序并进行错误检查,同时实现虚电路间的连接。TCP数据包中包括序号和确认,所以未按照顺序收到的包可以被排序,而损坏的包可以被重传。
TCP将它的信息送到更高层的应用程序,例如Telnet的服务程序和客户程序。应用程序轮流将信息送回TCP层,TCP层便将它们向下传送到IP层,设备驱动程序和物理介质,最后到接收方。
面向连接的服务(例如Telnet、FTP、rlogin、X Windows和SMTP)需要高度的可靠性,所以它们使用了TCP。DNS在某些情况下使用TCP(发送和接收域名数据库),但使用UDP传送有关单个主机的信息。

IP

IP层接收由更低层(网络接口层例如以太网设备驱动程序)发来的数据包,并把该数据包发送到更高层—TCP或UDP层;相反,IP层也把从TCP或UDP层接收来的数据包传送到更低层。IP数据包是不可靠的,因为IP并没有做任何事情来确认数据包是否按顺序发送的或者有没有被破坏,IP数据包中含有发送它的主机的地址(源地址)和接收它的主机的地址(目的地址)。
高层的TCP和UDP服务在接收数据包时,通常假设包中的源地址是有效的。也可以这样说,IP地址形成了许多服务的认证基础,这些服务相信数据包是从一个有效的主机发送来的。IP确认包含一个选项,叫作IP source routing,可以用来指定一条源地址和目的地址之间的直接路径。对于一些TCP和UDP的服务来说,使用了该选项的IP包好像是从路径上的最后一个系统传递过来的,而不是来自于它的真实地点。这个选项是为了测试而存在的,说明了它可以被用来欺骗系统来进行平常是被禁止的连接。那么,许多依靠IP源地址做确认的服务将产生问题并且会被非法入侵。

socket通讯知识

先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。

服务端代码

#include
#include
#include
#include
#include
#include
#include #define SERVER_PORT 8888
#define QUEUE 20
int main( ){int socket_fd;struct sockaddr_in sock_server; /*服务器sockaddr*/struct sockaddr_in sock_client; /*客户端sockaddr*/int sockfd; int len &#61; 0;char buff[1024&#43;1];memset( &sock_server, 0x00, sizeof( sock_server ) );memset( &sock_client, 0x00, sizeof( sock_client ) );/*创建套接字*/socket_fd &#61; socket( AF_INET, SOCK_STREAM, 0 );sock_server.sin_family&#61; AF_INET;sock_server.sin_port &#61; htons( SERVER_PORT );sock_server.sin_addr.s_addr &#61; htonl( INADDR_ANY );/*bind为套接字sockfd指定本地地址my_addr.my_addr的长度为addrlen(字节).传统的叫法是给一个套接字分配一个名字.*当使用 socket(),函数创建一个套接字时,它存在于一个地址空间(地址族), 但还没有给它分配一个名字*一般来说在使用 SOCK_STREAM 套接字建立连接之前总要使用 bind 为其分配一个本地地址*/if( bind( socket_fd, (struct sockaddr *)&sock_server, sizeof( sock_server ) ) &#61;&#61; -1){perror( "bind error" ); exit(1);}printf( "bind success,port:%d\n", SERVER_PORT ); /*在接收连接之前,首先要使用socket()创建一个套接字,然后调用listen()使其能够自动接收到来的连接并且为连接队列指定一个长度限制.*之后就可以使用 accept() 接收连接.listen()调用仅适用于 SOCK_STREAM 或者 SOCK_SEQPACKET 类型的套接字.*参数 backlog 指定未完成连接队列的最大长度.如果一个连接请求到达时未完成连接,队列已满,那么客户端将接收到错误:ECONNREFUSED.*或者,如果下层协议支持重发,那么这个连接请求将被忽略,这样客户端 在重试的时候就有成功的机会*/if( listen( socket_fd, QUEUE ) &#61;&#61; -1 ){perror( "listen error." );exit(1);} printf( "listen success.\n" ); while( 1 ){len &#61; sizeof( sock_client );sockfd &#61; accept( socket_fd, (struct sockaddr *)&sock_client, (socklen_t *)&len );if( sockfd < 0 ){continue;} printf( "accept() success.\n" );printf( "RECV:[%d],IP&#61;%s,PORT&#61;%d\n", sockfd, inet_ntoa(sock_client.sin_addr), ntohs(sock_client.sin_port) ); while( 1 ){memset( buff, 0x00, sizeof( buff ) ); if( recv( sockfd, buff, sizeof( buff )-1, 0 ) < 0 ){close( sockfd );printf( "recv error.\n" );break;}printf( "RECV FROM CLIENT:%s", buff ); if( !memcmp( buff, "exit", 4 ) ){close( sockfd );printf( "close sockfd\n" ); break;} /*send*/fflush( stdin );memset( buff, 0x00, sizeof( buff ) );printf( "SERVER:" );memset( buff, 0x00, sizeof( buff ) );if( NULL &#61;&#61; ( fgets( buff, sizeof( buff )-1, stdin ) ) ){perror( "fgets error.\n" ); close( sockfd );fflush( stdin );break; }fflush( stdin );send( sockfd, buff, sizeof( buff )-1, 0 ); if( memcmp( buff, "exit", 4 ) &#61;&#61; 0 || memcmp( buff, "kill", 4 ) &#61;&#61; 0 ){close( sockfd );printf( "close client socket.\n" ); break;}}if( !memcmp( buff, "kill", 4 ) ){close( sockfd );printf( "close server socket.\n" );break;}}exit(0);
}

客户端代码

#include
#include
#include
#include
#include
#include
#include
#include #define SERVER_IP "192.168.137.10"
#define SERVER_PORT 8888int main( ){int sockfd;struct sockaddr_in serverAddr;int len &#61; 0;int iRet &#61; 0;char buff[128];memset( &serverAddr, 0x00, sizeof( serverAddr ) );memset( buff, 0x00, sizeof( buff ) );sockfd &#61; socket( AF_INET, SOCK_STREAM, 0 );if( sockfd < 0 ){printf( "socket() errror:%s", strerror( errno ) );exit(1);}/*Convert server IP and PORT*/serverAddr.sin_family &#61; AF_INET; /*ipv4*/serverAddr.sin_addr.s_addr &#61; inet_addr( SERVER_IP );serverAddr.sin_port &#61; htons( SERVER_PORT );len &#61; sizeof( serverAddr );iRet &#61; connect( sockfd, ( struct sockaddr *) &serverAddr, (socklen_t) len );if( iRet < 0 ){printf( "connect() error:%s", strerror(errno) );exit(1);}printf( "connect success.\n" );printf( "begin to communicate.\n" );while( 1 ){memset( buff, 0x00, sizeof( buff ) );printf( "CLIENT:" );fflush( stdin ); if( fgets( buff, sizeof( buff )-1, stdin ) &#61;&#61; NULL ){printf( "fgets() error.\n" );fflush( stdin );exit(1);}fflush( stdin );/*send*/ iRet &#61; send( sockfd, buff, strlen(buff), 0 );if( iRet < 0 ){printf( "send() error:%s", strerror(errno) );exit(1);}if( !memcmp( buff, "exit", 4 ) ){printf( "close connection.\n" );close( sockfd );break;}/*recv*/memset( buff, 0x00, sizeof( buff ) );if( recv( sockfd, buff, sizeof(buff)-1, 0 ) < 0 ){printf( "recv error:%s", strerror( errno ) );close( sockfd );break;}printf( "RECV FROM SERVER:%s", buff );if( !memcmp( buff, "exit", 4 ) || !memcmp( buff, "kill", 4 ) ){printf( "close socket.\n" );close( sockfd );break;}}exit(0);
}


推荐阅读
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • JavaWeb中读取文件资源的路径问题及解决方法
    在JavaWeb开发中,读取文件资源的路径是一个常见的问题。本文介绍了使用绝对路径和相对路径两种方法来解决这个问题,并给出了相应的代码示例。同时,还讨论了使用绝对路径的优缺点,以及如何正确使用相对路径来读取文件。通过本文的学习,读者可以掌握在JavaWeb中正确找到和读取文件资源的方法。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • springmvc学习笔记(十):控制器业务方法中通过注解实现封装Javabean接收表单提交的数据
    本文介绍了在springmvc学习笔记系列的第十篇中,控制器的业务方法中如何通过注解实现封装Javabean来接收表单提交的数据。同时还讨论了当有多个注册表单且字段完全相同时,如何将其交给同一个控制器处理。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
  • 如何在php中将mysql查询结果赋值给变量
    本文介绍了在php中将mysql查询结果赋值给变量的方法,包括从mysql表中查询count(学号)并赋值给一个变量,以及如何将sql中查询单条结果赋值给php页面的一个变量。同时还讨论了php调用mysql查询结果到变量的方法,并提供了示例代码。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • 本文介绍了NetCore WebAPI开发的探索过程,包括新建项目、运行接口获取数据、跨平台部署等。同时还提供了客户端访问代码示例,包括Post函数、服务器post地址、api参数等。详细讲解了部署模式选择、框架依赖和独立部署的区别,以及在Windows和Linux平台上的部署方法。 ... [详细]
  • 概述H.323是由ITU制定的通信控制协议,用于在分组交换网中提供多媒体业务。呼叫控制是其中的重要组成部分,它可用来建立点到点的媒体会话和多点间媒体会议 ... [详细]
  • POCOCLibraies属于功能广泛、轻量级别的开源框架库,它拥有媲美Boost库的功能以及较小的体积广泛应用在物联网平台、工业自动化等领域。POCOCLibrai ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了VoLTE端到端业务详解|VoLTE用户注册流程相关的知识,希望对你有一定的参考价值。书籍来源:艾怀丽 ... [详细]
  • 三、寻找恶意IP并用iptables禁止掉找出恶意连接你的服务器80端口的IP,直接用iptables来drop掉它;这里建议写脚本来运行, ... [详细]
author-avatar
手机用户2502861713
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有