关于php和C语言接口的结构传递问题,udp,tcp通信

关于php和C语言接口的结构传递问题,udp,tcp通信
2008-01-07 12:41

在实际开发中,有时会遇到PHP和C语言结构的互相转化问题,这时候PHP的函数pack和unpack就能帮上大忙了.
pack()将数据打包成二进制串
unpack()从字串中的二进制串转化成指定的格式
Code Description
a NUL-padded string
A SPACE-padded string
h Hex string, low nibble first
H Hex string, high nibble first
c signed char
C unsigned char
s 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 byte
X 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 create
socket/n"
);
//绑定Socket到端口
$result = socket_bind($socket, $host, $port) or die(
"Could not bind to
socket/n"
);
// 开始监听链接
$result = socket_listen($socket, 3) or die(
"Could not set up socket
listener/n"
);
// accept incoming connections
// 另一个Socket来处理通信
$spawn = socket_accept($socket) or die(
"Could not accept incoming
connection/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 write
output/n"
);
// 关闭sockets
socket_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() 删除一个已经分配的iovec
socket_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,如果没有指定则默认当前socket
socket_recvmsg() 从iovec里接受消息
socket_select() 多路选择
socket_send() 这个函数发送数据到已连接的socket
socket_sendmsg() 发送消息到socket
socket_sendto() 发送消息到指定地址的socket
socket_set_block() 在socket里设置为块模式
socket_set_nonblock() socket里设置为非块模式
socket_set_option() 设置socket选项
socket_shutdown() 这个函数允许你关闭读、写、或者指定的socket
socket_strerror() 返回指定错误号的详细错误
socket_write() 写数据到socket缓存
socket_writev() 写数据到分散/聚合数组


=========================================
关于PHP与C语言SOCKET通信的问题
我用PHP(客户端)与C(服务器端)语言建立SOCKET连接,发送字符串的时候正常,但是发送整型数的时候就收到的是一堆莫名奇妙的数字,为什么?  
  PHP端程序如下:  
  <?php  
  $fp   =   fsockopen("202.112.25.163",   3333,   &$errno,   &$errstr,   10);  
  if(!$fp)   {  
                  echo   "$errstr   ($errno)<br>/n";  
  }   else   {  
              $a=0;  
                  fputs($fp,(string)$a);  
                  while(!feof($fp))   {  
                                  echo   fgets($fp,128);  
                  }  
                  fclose($fp);  
  }  
  ?>
解决:

fputs($fp,(string)$a);  
  ===>  
  fputs($fp,"$a");  
   
  把  
  fputs($fp,(string)$a);  
  改为  
  fputs($fp,"$a");  

==========================================================

in   PHP   manual   :  
   
  Socket   example:   Simple   TCP/IP   client  
   
  This   example   shows   a   simple,   one-shot   HTTP   client.   It   simply   connects   to   a   page,   submits   a   HEAD   request,   echoes   the   reply,   and   exits.    
   
  <?php  
  error_reporting(E_ALL);  
   
  echo   "<h2>TCP/IP   Connection</h2>/n";  
   
  /*   Get   the   port   for   the   WWW   service.   */  
  $service_port   =   getservbyname('www',   'tcp');  
   
  /*   Get   the   IP   address   for   the   target   host.   */  
  $address   =   gethostbyname('www.example.com');  
   
  /*   Create   a   TCP/IP   socket.   */  
  $socket   =   socket_create(AF_INET,   SOCK_STREAM,   SOL_TCP);  
  if   ($socket   <   0)   {  
          echo   "socket_create()   failed:   reason:   "   .   socket_strerror($socket)   .   "/n";  
  }   else   {  
          echo   "OK./n";  
  }  
   
  echo   "Attempting   to   connect   to   '$address'   on   port   '$service_port'...";  
  $result   =   socket_connect($socket,   $address,   $service_port);  
  if   ($result   <   0)   {  
          echo   "socket_connect()   failed./nReason:   ($result)   "   .   socket_strerror($result)   .   "/n";  
  }   else   {  
          echo   "OK./n";  
  }  
   
  $in   =   "HEAD   /   HTTP/1.1/r/n";  
  $in   .=   "Host:   www.example.com/r/n";  
  $in   .=   "Connection:   Close/r/n/r/n";  
  $out   =   '';  
   
  echo   "Sending   HTTP   HEAD   request...";  
  socket_write($socket,   $in,   strlen($in));  
  echo   "OK./n";  
   
  echo   "Reading   response:/n/n";  
  while   ($out   =   socket_read($socket,   2048))   {  
          echo   $out;  
  }  
   
  echo   "Closing   socket...";  
  socket_close($socket);  
  echo   "OK./n/n";  
  ?>    
====================================================
I need a php page to connect to a python created socket and sent and
 receive data. below is the python code which opens a socket on the
 localhost @ port 21567:

 #!/usr/bin/python2
 from socket import *
 from time import time,ctime

 HOST ='127.0.0.1'
 PORT = 21567
 BUFSIZ = 1024
 ADDR = (HOST,PORT)
 tcpS = socket(AF_INET,SOCK_STREAM)
 tcpS.bind(ADDR)
 tcpS.listen(5)

 while 1:
 print "waiting for connection..."
 tcpC ,addr = tcpS.accept()
 print '...conected from:',addr

 while 1:
 data = tcpC.receive(BUFSIZ)
 if not data: break
 tcpC.send('[%s] %s' % (ctime(time()),data))
 tcpC.close()
 tcpS.close()

 ################## end of code

 The above works fine I can attach via a python client on another machine.

 Below is the php code for the page to attach to the socket at present
 (for debugging) they are running on the same machine, it attaches and
 sends the message "it is working" to the socket @ 21567 and it sould
 return with the same message timestamped:

 <?php
 error_reporting (E_ALL);

 echo "<h2Socket Test</h2/n";
 $address = '127.0.0.1';
 $service_port = 21567;
 $socket = socket_create (AF_INET, SOCK_STREAM, 0);
 if ($socket < 0)
 {
 echo "socket_create() failed: reason: " . socket_strerror ($socket) .
 "/n";
 }
 else
 {
 echo "OK./n";
 }
 echo "Attempting to connect to '$address' on port '$service_port'...";
 $in = "is it working";
 $out = '';
 echo "Sending Info request...";
 socket_write ($socket, $in, strlen ($in));
 echo "OK./n";echo "Reading response:/n/n";
 while ($out = socket_read ($socket, 1024))
 {
 echo $out;
 }

 echo "Closing socket...";
 socket_close ($socket);
 echo "OK./n/n";

 ?

 below are the results:

 Socket Test
 OK. Attempting to connect to '127.0.0.1' on port '21567'...Sending Info
 request...
 Warning: socket_write() unable to write to socket 10 [32]: Broken pipe in
 /var/www/html/tcpsock.php on line 20
 OK. Reading response:
 Warning: socket_read() unable to read from socket [107]: Transport
 endpoint is not connected in /var/www/html/tcpsock.php on line 22
 Closing socket...OK.


====================================================


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言是一种通用的编程语言,用于开发各种类型的应用程序。在C语言中,可以使用socket库来创建和管理网络连接。下面是关于创建socketTCPUDP区别的介绍: 1. 创建socket: 在C语言中,可以使用socket函数来创建一个socket对象。该函数位于<sys/socket.h>头文件中,通过指定协议族(如AF_INET)和套接字类型(如SOCK_STREAM或SOCK_DGRAM),可以创建不同类型的socket。 2. TCPUDP区别: TCP(传输控制协议)和UDP(用户数据报协议)是两种常见的传输层协议,用于在网络上传输数据。它们之间的主要区别如下: - 连接性:TCP是面向连接的协议,而UDP是无连接的协议。TCP通信之前需要建立连接,而UDP则直接发送数据包。 - 可靠性:TCP提供可靠的数据传输,它使用确认和重传机制来确保数据的完整性和可靠性。UDP则不提供可靠性保证,它只是简单地将数据包发送出去,不关心是否到达目标。 - 速度:由于TCP提供了可靠性保证,它的传输速度相对较慢。而UDP没有额外的确认和重传机制,因此传输速度较快。 - 数据包顺序:TCP保证数据包按照发送的顺序进行传输,而UDP则不保证数据包的顺序。 总的来说,TCP适用于需要可靠传输和顺序性的应用场景,如文件传输、网页浏览等。而UDP适用于实时性要求较高、对数据完整性要求不高的应用场景,如音视频传输、实时游戏等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值