怎样使用php实现tcpudp通讯

怎样使用php实现tcpudp通讯,第1张

1.在socket_bind的时候ip地址不能真回环地址如乎银祥127.0.0.1

2.server.php后台跑起来岁搏的时候nohup php server.php >/var/tmp/a.log 2>&1 &

一: udp 方式

1) server.php

<?php //error_reporting( E_ALL ) set_time_limit( 0 ) ob_implicit_flush() $socket = socket_create( AF_INET, SOCK_DGRAM, SOL_UDP ) if ( $socket === false ) {echo "socket_create() failed:reason:" . socket_strerror( socket_last_error() ) . "\n" } $ok = socket_bind( $socket, '202.85.218.133', 11109 ) if ( $ok === false ) {echo "socket_bind() failed:reason:" . socket_strerror( socket_last_error( $socket ) ) } while ( true ) {$from = "" $port = 0 socket_recvfrom( $socket, $buf,1024, 0, $from, $port ) echo $buf usleep( 1000 ) } ?>

2) client.php

<?php $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP) $msg = 'hello' $len = strlen($msg) socket_sendto($sock, $msg, $len, 0, '202.85.218.133', 11109) socket_close($sock) ?>

二: TCP 方式

1)server.php

<?php //error_reporting( E_ALL ) set_time_limit( 0 ) ob_implicit_flush() $socket = socket_create( AF_INET, SOCK_STREAM, SOL_TCP ) socket_bind( $socket, '192.168.2.143', 11109 ) socket_listen($socket) $acpt=socket_accept($socket) echo "Acpt!\n" while ( $acpt ) {$words=fgets(STDIN) socket_write($acpt,$words) $hear=socket_read($acpt,1024) echo $hear if("bye\搏闭r\n"==$hear){ socket_shutdown($acpt) break }usleep( 1000 ) } socket_close($socket) ?>

2) client.php

<?php $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) $con=socket_connect($socket,'192.168.2.143',11109) if(!$con){socket_close($socket)exit} echo "Link\n" while($con){ $hear=socket_read($socket,1024) echo $hear $words=fgets(STDIN) socket_write($socket,$words) if($words=="bye\r\n"){break} } socket_shutdown($socket) socket_close($sock) ?>

在工业控制中,Modbus RTU CRC16的校验码用的比较广泛,包括本人富士产品中,PC与伺服电机以及PC与VP系列的变频器的Modbus RTU通讯中都使用高纯到了CRC16.

而对CRC16的计算的方式基本上有2种:第一种,使用双循环依照CRC的计算方法进行计算,第二种,采用查表的方戚态咐式。本人愚钝无比,从网络上搜来的查表法都与实际的正确CRC16的结果有所差异,因此编写了一个小程序供自己使用。

软件的界面很简单,输入诸如“010303020014”的值,然后每2个字符作为一个字节,填入字节数,然后就可以计算出校验码,校验码的多项式为:X16+X15+X2+1.

程序界面如下:

实现的源代码如下:

unit Unit1

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls

type

TForm1 = class(TForm)

Edit1: TEdit

Button1: TButton

Edit2: TEdit

Edit3: TEdit

Label1: TLabel

Label2: TLabel

Label3: TLabel

Memo1: TMemo

Label4: TLabel

function CalCRC16(AData:array of ByteAStart,AEnd:Integer):Word

procedure Button1Click(Sender: TObject)

private

{ Private declarations }

public

{ Public declarations }

end

var

Form1: TForm1

implementation

{$R *.dfm}

//××××××××××××××××××××××××××

// CalCRC16用于计算Modbus RTU的CRC16

// 多项式公式为X16+X15+X2+1

//××××××××××××××××××××××××××

function TForm1.CalCRC16(AData:array of ByteAStart,AEnd:Integer):Word

const

GENP=$A001 //多项式公式X16+X15+X2+1(1100 0000 0000 0101)

var

crc:Word

i:Integer

tmp:Byte

procedure CalOneByte(AByte:Byte) //计算1个字节的校验码

var

j:Integer

begin

crc:=crc xor AByte //将数据与CRC寄存器的低8位进行异或

for j:=0 to 7 do //对每一位进行校验

begin

tmp:=crc and 1 //取闭游出最低位

crc:=crc shr 1 //寄存器向右移一位

crc:=crc and $7FFF //将最高位置0

if tmp=1 then //检测移出的位,如果为1,那么与多项式异或

crc:=crc xor GENP

crc:=crc and $FFFF

end

end

begin

crc:=$FFFF//将余数设定为FFFF

for i:=AStart to AEnd do //对每一个字节进行校验

CalOneByte(AData[i])

Result:=crc

end

procedure TForm1.Button1Click(Sender: TObject)

var

Data:array[0..255] of Byte

i,j,Count:Integer

Res:Word

szData:string

begin

szData:=Form1.Edit2.Text //读入欲校验的字符串

Count:=StrToInt(form1.Edit3.Text)//读入需要计算的字符串长度

i:=1

j:=0

for j:=0 to Count-1 do

begin

if (i mod 2)=0 then//每2个字符放入一个字节中

i:=i+1

if i>=Length(szData) then

exit

Data[j]:=StrToInt('$'+copy(szData,i,2))//取出字符并转换为16进制数

i:=i+1

end

Res:=CalCRC16(Data,Low(Data),Count-1)

form1.Edit1.Text:=IntToHex(Res,4)

end

end.


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/12333568.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存