六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 53|回复: 0

PHP和C通过Socket通信--UDP

[复制链接]

升级  1.67%

57

主题

57

主题

57

主题

举人

Rank: 3Rank: 3

积分
205
 楼主| 发表于 2013-1-19 04:07:43 | 显示全部楼层 |阅读模式
在实际开发中,有时会遇到PHP和C语言结构的互相转化问题,这时候PHP的函数pack和unpack就能帮上大忙了.pack()将数据打包成二进制串unpack()从字串中的二进制串转化成指定的格式Code Descriptiona NUL-padded stringA SPACE-padded stringh Hex string, low nibble firstH Hex string, high nibble firstc signed charC unsigned chars signed short (always 16 bit, machine byte order)S unsigned short (always 16 bit, machine byte order)n unsigned short (always 16 bit, big endian byte order)v unsigned short (always 16 bit, little endian byte order)i signed integer (machine dependent size and byte order)I unsigned integer (machine dependent size and byte order)l signed long (always 32 bit, machine byte order)L unsigned long (always 32 bit, machine byte order)N unsigned long (always 32 bit, big endian byte order)V unsigned long (always 32 bit, little endian byte order)f float (machine dependent size and representation)d double (machine dependent size and representation)x NUL byteX Back up one byte@ NUL-fill to absolute position例如,typedef struct _BorrowInfo{char mobile[32];char area[8];int   type;int   ret} BorrowInfo<?//将PHP变量转成结构$type=100;$mobile="13901234567";$ret=0;$area="BJ";$returnstr=sprintf("%-32s,$mobile).sprintf("%-8s,$area).pack("l",$type).pack("l",$ret);//将结构转成php变量//对于字符型变量可以直接取得$moible=substr($returnstr,0,32);$area=substr($returnstr,32,8);$fuckarray=unpack("nint",substr($returnstr,40,4));$type=$fuckarray['int'];//RET变量也可以向type类似取得?>需要注意的事,C语言结构由于内存对齐方式和机器字节顺序问题,需要对代码进行微调,才能正常使用.比如将结构体构体的手机号设为25位,则整个结构sizeof后是44字节,而不是41字节,切记.否则用PHP转成的结构C语言是解析不了的.------------------------------------------------/*server.c*/#include <sys/types.h>#include <sys/socket.h>#include <string.h>#include <stdio.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>main(){     int sock;     struct sockaddr_in server,client;     int recvd,snd;     int structlength;     char * server_ip = "128.168.10.1";/*server ip address*/     int port = 8888;     char recvbuf[2000],sendbuf[2000];         char str1[]="I have received:\n";     memset((char *)&server,0,sizeof(server));     server.sin_family = AF_INET;     server.sin_addr.s_addr = inet_addr(server_ip);     server.sin_port = htons(port);     memset((char *)&client,0,sizeof(client));     client.sin_family = AF_INET;     client.sin_addr.s_addr = htonl(INADDR_ANY);     client.sin_port = htons(port);         if((sock = socket (AF_INET,SOCK_DGRAM,0)) < 0 ){         printf("socket create error!\n");         exit(1);     }         structlength = sizeof(server);     if( bind(sock,(struct sockaddr *) &server,structlength) < 0){         printf("socket bind error!\n");         perror("bind");         exit(1);     }     while(1){         structlength = sizeof(client);                         printf("waiting.......\n");         recvd = recvfrom(sock,recvbuf,sizeof(recvbuf),0,             (struct sockaddr *) & client,&structlength);         if(recvd < 0){             perror("recvfrom");             exit(EXIT_FAILURE);             }         else{             printf("received:%s\n",recvbuf);                     memset(sendbuf,0,strlen(sendbuf));             memcpy(sendbuf,str1,strlen(str1));                                 snd = sendto(sock,sendbuf,strlen(str1),0,             (struct sockaddr *) &client,structlength);             if(snd < 0){             perror("sendto");             exit(1);             }             printf("sendok!\n");         }                     }                 close(sock);}/*gcc -o server server.c生成server程序,在服务器端运行./server*//*client.php*/<?php$server_ip="128.168.10.1";$port = 8888;$sock=@socket_create(AF_INET,SOCK_DGRAM,0);if(!$sock){     echo "socket create failure";}if($buf=="")     $buf="hello,how are you!\n";if(!@socket_sendto($sock,$buf,strlen($buf),0,"128.168.10.1",8888)){     echo "send error\n";     socket_close($sock);     exit();}$buf="";$msg="";if(!@socket_recvfrom($sock,$msg,256,0,&$server_ip,&$port)){     echo "recvieve error!";     socket_close($sock);     exit();}echo trim($msg)."\n";socket_close($sock);?><form action="client.php" method="post"><input type=text name=buf><input type=submit value="submit"></form>/*这个过程很简单,就是客户端提交一个信息,服务端接收,并返回给客户端一个"接收到"的确认信息。*/--------------------------------------------------------<?// 设置一些基本的变量$host = "192.168.1.99";$port = 1234;// 设置超时时间set_time_limit(0);// 创建一个Socket$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not createsocket\n");//绑定Socket到端口$result = socket_bind($socket, $host, $port) or die("Could not bind tosocket\n");// 开始监听链接$result = socket_listen($socket, 3) or die("Could not set up socketlistener\n");// accept incoming connections// 另一个Socket来处理通信$spawn = socket_accept($socket) or die("Could not accept incomingconnection\n");// 获得客户端的输入$input = socket_read($spawn, 1024) or die("Could not read input\n");// 清空输入字符串$input = trim($input);//处理客户端输入并返回结果$output = strrev($input) . "\n";socket_write($spawn, $output, strlen ($output)) or die("Could not writeoutput\n");// 关闭socketssocket_close($spawn);socket_close($socket);?>--------------------------------------socket_accept() 接受一个Socket连接socket_bind() 把socket绑定在一个IP地址和端口上socket_clear_error() 清除socket的错误或者最后的错误代码socket_close() 关闭一个socket资源socket_connect() 开始一个socket连接socket_create_listen() 在指定端口打开一个socket监听socket_create_pair() 产生一对没有区别的socket到一个数组里socket_create() 产生一个socket,相当于产生一个socket的数据结构socket_get_option() 获取socket选项socket_getpeername() 获取远程类似主机的ip地址socket_getsockname() 获取本地socket的ip地址socket_iovec_add() 添加一个新的向量到一个分散/聚合的数组socket_iovec_alloc() 这个函数创建一个能够发送接收读写的iovec数据结构socket_iovec_delete() 删除一个已经分配的iovecsocket_iovec_fetch() 返回指定的iovec资源的数据socket_iovec_free() 释放一个iovec资源socket_iovec_set() 设置iovec的数据新值socket_last_error() 获取当前socket的最后错误代码socket_listen() 监听由指定socket的所有连接socket_read() 读取指定长度的数据socket_readv() 读取从分散/聚合数组过来的数据socket_recv() 从socket里结束数据到缓存socket_recvfrom() 接受数据从指定的socket,如果没有指定则默认当前socketsocket_recvmsg() 从iovec里接受消息socket_select() 多路选择socket_send() 这个函数发送数据到已连接的socketsocket_sendmsg() 发送消息到socketsocket_sendto() 发送消息到指定地址的socketsocket_set_block() 在socket里设置为块模式socket_set_nonblock() socket里设置为非块模式socket_set_option() 设置socket选项socket_shutdown() 这个函数允许你关闭读、写、或者指定的socketsocket_strerror() 返回指定错误号的详细错误socket_write() 写数据到socket缓存socket_writev() 写数据到分散/聚合数组PHP socket 编程中的超时设置,网上找了半天也没找到,贴出来分享之。设置$socket 发送超时1秒,接收超时3秒:$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);socket_set_option($socket,SOL_SOCKET,SO_RCVTIMEO,array("sec"=>1, "usec"=>0 ) );socket_set_option($socket,SOL_SOCKET,SO_SNDTIMEO,array("sec"=>3, "usec"=>0 ) );
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表