python unsigned long_派森吧 - pythonpub.com | 享受python带来的便利以及快乐

python提供了丰富的内置类型:比如字符串,整数,浮点数,列表,元组,字典,但是没有提供类似C语言的结构体类型,如果我们用python来实现客户端,用C来是实现服务器的话,需要用python来实现C的结构体,并且用UDP或者TCP传输。

python中的struct模块专门用来处理python的值和C的类型结构之间的转换,此模块执行的Python Python字符串表示的值和C的结构之间的转换。这可以用来处理的二进制数据存储在文件或网络连接,以及其他来源。

struct模块主要的方法有三种pack、unpack、calcsize:

struct.pack(fmt,v1,v2,.....) 将v1,v2等参数的值进行包装,包装的方法由fmt指定,被包装的参数必须严格符合fmt,最后返回字符串。

struct.unpack(fmt,string) 返回一个由解包数据(string)得到的一个元组(tuple)。

struct.calcsize(fmt),用来计算fmt格式所描述的结构的大小,也等于len(string)。

下面来介绍一下fmt(格式字符串格式):默认情况下,C类型的代表在机器的原生格式和字节顺序,如果必要的(按C编译器所使用的规则)跳过填充字节,正确对齐。此外,格式字符串的第一个字符,可以用来表明字节顺序,大小和压缩数据的对齐,根据下表:(默认情况是不加,实际上是按照@要求表示字节顺序以及字节,对齐)

Character

Byte order

Size

Alignment

@

native

native

native

=

native

standard

none

<

little-endian

standard

none

>

big-endian

standard

none

!

network (= big-endian)

standard

none

格式字符串除了上表的第一个字符外,还支持一下格式:

Format

C Type

Python type

Standard size

Notes

x

pad byte

no value

c

char

string of length 1

1

b

signed char

integer

1

(3)

B

unsigned char

integer

1

(3)

?

_Bool

bool

1

(1)

h

short

integer

2

(3)

H

unsigned short

integer

2

(3)

i

int

integer

4

(3)

I

unsigned int

integer

4

(3)

l

long

integer

4

(3)

L

unsigned long

integer

4

(3)

q

long long

integer

8

(2), (3)

Q

unsigned long long

integer

8

(2), (3)

f

float

float

4

(4)

d

double

float

8

(4)

s

char[]

string

p

char[]

string

P

void *

integer

(5), (3)

例子:直接使用library上的例子

>>>from struct import *

>>>pack('hhl', 1, 2, 3)  包装

'x00x01x00x02x00x00x00x03'

>>>unpack('hhl', 'x00x01x00x02x00x00x00x03')  解包

(1, 2, 3)

>>>calcsize('hhl')

8

最后来讲一下关键的问题:如何使用python来模拟C的结构体?

首先来看C的结构体如下面的形式:

struct info

{

int age;

float score;

char name1[3];

};

typedef struct my_data

{

char name[10];

struct info test;

} MY_DATA;

如果用python来进行包装的话,可以使用下面的形式:

name = "sleetdrop"

age = 28

score = 1000

name1="aes"

info = struct.pack("10sif3s", name,age, score, name1)

最后看看用python写的客户端,用C写的服务器,用UDP传输信息。

python代码:(ip地址和端口号根据自己需要更改)

import socket, struct

serviceip = "10.0.0.28"

port = 3000

name = "sleetdrop"

age = 28

score = 1000

name1="aes"

info = struct.pack("10sif3s", name,age, score, name1)

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

s.sendto(info, (serviceip, port))

C的代码:

#include #include #include #include #include #include #include #include struct info

{

int age;

float score;

char name1[3];

};

typedef struct my_data

{

char name[10];

struct info test;

} MY_DATA;

void dg_echo(int, struct sockaddr *, socklen_t);

int

main(int argc, char **argv)

{

int sockfd;

struct sockaddr_in svraddr, cliaddr;

sockfd = socket(AF_INET, SOCK_DGRAM, 0);

bzero(&svraddr, sizeof(svraddr));

svraddr.sin_family = AF_INET;

svraddr.sin_addr.s_addr = htonl(INADDR_ANY);

svraddr.sin_port = htons(3000);

bind(sockfd, (struct sockaddr *) &svraddr, sizeof(svraddr));

dg_echo(sockfd, (struct sockaddr *) &cliaddr, sizeof(cliaddr));

}

void

dg_echo(int sockfd, struct sockaddr *pcliaddr, socklen_t clilen)

{

int n;

socklen_t len;

MY_DATA mydata;

bzero(&mydata, sizeof(MY_DATA));

for( ; ; ) {

len = clilen;

n = recvfrom(sockfd, &mydata, sizeof(MY_DATA), 0, pcliaddr, &len);

printf("Name:%stAge:%dtScore:%fttest:%sn", mydata.name, mydata.test.age, mydata.test.score,mydata.test.name1);

}}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值