socket 消息头传输

quansheng3510 2011-01-07 03:11:38
最近做一个基于socket传输的消息头验证机制,服务器发送带特定消息头的消息,然后客户端对这个消息进行解析,这个消息的消息头据有特定的格式,只有消息头一样,才可以进行通信,然后本地也要把字符串拼合成特定的格式,然后以二进制传输,要求用php的socket做,请大家给些思路。(一直网页编程,tcp的不是很懂
...全文
638 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
skyaspnet 2011-01-17
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 quansheng3510 的回复:]
来个高手啊,我要的不是socket的知识,只是要一些处理消息头,消息体,组合为二进制和c进行通信的知识
[/Quote]

需要看计算机网络SOCKEI通信的基础知识:L
socket 基础知识



概述



socket 是 TCP/IP 协议的最流行的一种网络编程接口。它与 TCP/IP 一起最早实现于 4.1BSD UNIX 系统中,主要用于传送级( TCP,UDP )编程。



socket 往往称为套接口,套接口用于网络中两个通信实体间的通信,两个实体可以存在于同一机器的不同进程中或不同机器的进程中。



套接口就好像 UNIX 中 pipe (管道),通信双方进程通过它来与对方发送或接受数据。如同 pipe 用文件描述字表示一样, socket 也用文件描述字表示,也称为套接口描述字,或简称套接字。在网络编程时要用套接字表示通信的对方。但两者不同的是, pipe 的通信双方在一台机器上,共用一个 pipe ,双方使用不同的文件描述字;而 socket 通信双方一般在不同机器上,因而通信双方均有一 socket 和对应的套接字负责通信,当然他们之间必须连接起来。



网络中每个通信实体的 socket 是用一个三元组标识的。三元组指的是:协议族(地址族),网络地址、和传输层端口 (本文目前只介绍 Ipv4 )。通信双方的一个连接是用网络五元组来标识的,它是由双方相同协议族的两个本地三元组合成的。网络五元组指的是:协议族(地址族)、本地网络地址、本地端口、远程网络地址和远程端口。 上述五元组往往称为全相关。而三元组往往称为半相关



套接口分为若干类型,常用的是 SOCK_STREAM 和 SOCK_DGRAM 。 SOCK_STREAM 是面向连接的套接字,使用的协议是 TCP ,通信的双方通过三次握手建立起虚拟的连接线路,通信的过程是可靠的。而 SOCK_DGRAM 是面向非连接的套接字,使用的协议是 UDP ,通信双方以数据包的方式进行通信,通信的可靠性就不能得到保证。本项目要求采用 SOCK_STREAM 类型。





客户机 / 服务器计算模式



在 TCP/IP 网络应用中 , 通信双方相互作用采用客户 / 服务器模式 , 即客户端向服务器发出请求 , 服务器接收到请求后提供相应的服务。一种常见的面向连接的运行方式如下:



服务器方(首先启动):



1. 打开一通信通道并告知本地主机,它愿意在某一公认地址端口上 ( 周知口,如 http 为 80) 接受客户请求。



2. 等待客户请求到达该端口。



3. 接收并处理该请求,发送处理结果。如果是并发服务器,则要建立( fork )一新的子进程来处理这个客户请求。服务完成后,关闭这个新进程与客户的通信连接,并终止该进程。



4. 返回第二步,等待下一个客户请求。



客户方 :



1. 打开一通信通道,并连接到服务器所在主机的特定端口。



2 .如服务器接受了这个连接,则向它发出服务请求报文,等待并接收应答;



3. 请求结束后关闭通信通道。



从上面的运行过程可知:



1 .客户与服务器进程的作用是非对称的。



2. 服务进程一般是先于客户请求启动的。只要系统运行,该进程一直存在,直到正常终止或者强迫终止。





五元组格式(协议,本地 IP ,本地端口,远方 IP ,远方端口)的建立过程

服务器一般都有两个功能:监听 和 处理

在监听的时候,协议 / 本地 IP/ 本地端口(监听端口)都是确定的,当收到客户端的报文时,远方 IP 就是报文的源 IP 地址,远方端口就是报文的源端口,这样一来五元组就确定了。

然后服务器进入处理阶段,需要开启一个新的线程与客户端交互,当然就需要确定一个新的五元组,这时候协议 / 本地 IP/ 远方 IP/ 远方端口都来自监听阶段确定的五元组,而本地端口会在 1024 以上随机选取 (不再使用监听端口,以便监听其他客户端的请求)。

客户端的话正好相反,在发送请求时采用随机的本地端口 ,而接受响应时采用服务器的源端口作为远方端口。





系统调用



1. 创建套接字

#include <sys/types.h>;

#include <sys/socket.h>;



int socket(int family, int type, int protocol);



这是进行套接字通信的第一步,就是创建套接口。参数 family 表示所使用的协议族。参数 type 可以是 SOCK_STREAM 或 SOCK_DGRAM 。 SOCK_STREAM 是指面向连接的通信,而 SOCK_DGRAM 是面向非连接的数据报方式。参数 protocol 描述的是协议种类,一般设为 0 。



Socket 函数用于建立三元组中的协议族部分 。



此系统调用如果成功就返回的是套接字,以后的所有的对此套接口的操作都需引用这个描述字。如果调用失败,就返回 -1 ,并在全局变量 errno 保存错误的类型。



2. 绑定套接字

#include <sys/types.h>;

#include <sys/socket.h>;



int bind(int sockfd, cost struct sockaddr * saddr, socklen_t addrlen);



bind( ) 系统调用的作用是将由 socket( ) 所创建的套接字和地址结构 sockaddr 的一个实例相关联,其中含有本地的信息如 IP 地址、端口号。



bind 函数用于建立三元组中的本地 IP 地址和本地端口号部分。



参数 sockfd 是在此前用 socket 系统调用创建的套接字, sa 是指向结构 sockaddr 一个实例的指针。这个实例的类型一般是 sockaddr_in ,在调用时需要进行强制转换( struct sockaddr * ) &saddr (其中 saddr 是 sockaddr_in 类型)。参数 addrlen 是结构 sockaddr 的大小即 sizeof ( struct sockaddr )。其中套接字的地址和端口可以在程序中指定,也可以由系统分配。



3. 监听

#include <sys/socket.h>;



int listen( int sockfd, int backlog ) ;



用 TCP 进行网络通信,服务器端要经历几个状态,当调用 socket( ) 和 bind( ) 后,虽然套接字已经建立起来,但是其状态是 CLOSED 即关闭状态。要进行通信就必须将套接字打开。对于服务器端来说要被动打开,这就是 listen( ) 的功能。



下面就可以用 accept( ) 和 connect() 建立连接。这个过程其实就是 TCP 的“三次握手”。



4. 接受连接

#include <sys/socket.h>;



int accept( int sockfd, struct sockaddr * client_addr, socklen_t *addrlen);



服务器调用 accept( ) 来接受连接。当客户与服务器连接( connect )并且连接成功(三次握手)后 accept 则返回另一个套接字。这个新创建的套接字称为“连接套接字 ”。服务器利用这个套接字来传输数据。而前面用 socket( ) 调用产生的套接字则称之为“监听套接字”,这个套接字专门监听来自客户端的请求。



参数 sockfd 是由 socket( ) 创建的连接套接字。 client_addr 是指向结构 sockaddr 的一个实例的指针,在返回时用来存放请求连接的客户端的 IP 地址、端口信息。参数 addrlen 存放结构 * client_addr 的大小。



access 完成后通信双方两个三元组组成的五元组就建立起来了。



5. 连接服务器

#include <sys/types.h>;

#include <sys/socket.h>;



int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);



客户端使用这个系统调用来连接目的主机(服务器)的指定端口,以便和目的主机 ( 在 access 中等待 ) 进行通信。



sockfd 是客户机的系统调用 socket() 返回的套接字。 serv_addr 指向目的地 ( 服务器)端口和 IP 地址的数据结构 struct sockaddr 。 addrlen 设置为 sizeof(struct sockaddr) 。



connect 完成后通信双方两个三元组组成的五元组就建立起来了。
fxs_2008 2011-01-17
  • 打赏
  • 举报
回复
如果你的协议不是http的,如更底层的协议,建议去相关网络通信论坛看看

http协议分消息头和消息体及传输状态,但不知是不是你所说的!

quansheng3510 2011-01-17
  • 打赏
  • 举报
回复
来个高手啊,我要的不是socket的知识,只是要一些处理消息头,消息体,组合为二进制和c进行通信的知识
ihefe 2011-01-07
  • 打赏
  • 举报
回复
参考
http://topic.csdn.net/t/20010823/18/253299.html#r_1691975

http://topic.csdn.net/t/20001223/08/51320.html#r_203057
quansheng3510 2011-01-07
  • 打赏
  • 举报
回复
不要跟我说什么fsockopen,现在是怎么按协议分解和组合消息头,规定的消息头是4字节固定长度+内容长度
zhongqixing1104 2011-01-07
  • 打赏
  • 举报
回复
去查看下fsockopen的用法

21,886

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧