« 网络监视工具NTOP | 首页 | 享受孤单 »

用pack实现UDP包在PYTHON与C结构体透明通信

  Python是一个好东西,是如此的适合写身边的一些小toolkit。测试程序就是其中一例。比如用C写了一个server,就可以用python写一个client来测试这个server。但遇到一个小问题,就是在UDP传输的时候UDP包中信息的各个字段是用结构体定义的。但Python本身是模糊类型的动态语言,怎么样才能构造UDP包的时候符合C语言结构体的结构呢。Yahoo search找到这篇文章,才想起来perl和php也是有这个pack函数的,以前看到这个函数的时候都是略过,没想到有啥具体用处。看来自己还是一根墙上芦苇啊,BS自己一下。

顺便改出两段简陋的code来说明这个问题.

/*
 * udpsrv.c
 * 
 * The test udp server, source code is stolen from UNP 3ed ED.
 *
 */

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

typedef struct my_data
{
	char name[10];
	int age;
	float score;
} 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:%s\tAge:%d\tScore:%f\n", mydata.name, mydata.age, mydata.score);
	}

}


#!/usr/bin/python

# Filename: udpcli.py

# a simple udp client

import socket, struct

hostname = 'localhost'
port = 3000

host = socket.gethostbyname(hostname)

name = 'sleetdrop'
age = 18
score = 100

buf = struct.pack("10sif", name, age, score)

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto(buf, (host, port))


在linux上编译并起动udp服务器
$gcc udpsrv.c -o udpsrv
$./udpsrv

在另一个term执行
$python udpcli.py

在服务器所在term会得到如下输出:
Name:sleetdrop  Age:18  Score:100.000000



引用:

本篇引用地址:
http://www.vetcafe.net/cgi-bin/mt3/mt-tb.cgi/2568

评论:

pack/unpack的确很强大, python真有魅力, 你终于也开始贴代码了.

发表评论

(如果您以前没在这里发表过评论,也许您发表的评论需要Blog主人的审核才能显示在这里,感谢您的静候。)