Mixed programming examples of python and C
- 2020-04-02 13:40:38
- OfStack
How was recently to test speed, because some business server need to close the icmp, so use ordinary ping will not be able to adapt to my needs, and their simple wrote a program based on the TCP port ping, because c execution efficiency is good, but the development of low efficiency, and python development efficiency is high, but performance is better than c, due to large-scale use, so the core part of the code to implement in c, and the partial implementation into a python module, call c by python module, post code below
#include <Python.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/time.h>
static double mytime(void)
{
struct timeval tv;
if (gettimeofday(&tv, NULL) == -1)
return 0.0;
return (double)tv.tv_usec + (double)tv.tv_sec * 1000000;
}
static PyObject *
tcpping(PyObject *self, PyObject *args )
{
struct sockaddr_in addr;
struct hostent *hp;
double time;
char *host = NULL;
int fd;
int port, timeout;
if (!PyArg_ParseTuple(args, "sii", &host, &port, &timeout))
return NULL;
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
return Py_BuildValue("d", -1.0);
}
bzero((char *)&addr, sizeof(addr));
if ((hp = gethostbyname(host)) == NULL) {
return Py_BuildValue("d", -2.0);
}
bcopy(hp->h_addr, &addr.sin_addr, hp->h_length);
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = timeout * 1000;
double stime = mytime();
if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
return Py_BuildValue("d", -3.0);
}
fd_set read, write;
FD_ZERO(&read);
FD_ZERO(&write);
FD_SET(fd, &read);
FD_SET(fd, &write);
if (select(fd + 1, &read, &write, NULL, &tv) == 0) {
close(fd);
return Py_BuildValue("d", -4.0);
}
double etime = mytime();
time = etime - stime;
if (!FD_ISSET(fd, &read) && !FD_ISSET(fd, &write)) {
close(fd);
return Py_BuildValue("d", -4.0);
}
close(fd);
return Py_BuildValue("d", time/1000);
}
static struct PyMethodDef portping_methods[] = {
{"tcpping", tcpping, METH_VARARGS},
{NULL, NULL}
};
void inittcpportping( )
{
(void) Py_InitModule("tcpportping", portping_methods);
}
Compile as a python module
gcc tcpportping.c -I/usr/include/python2.4 -shared -L/usr/bin -fpic -lpython2.4 -o tcpportping.so
Here is the code for python to call the c module:
#!/usr/bin/env python
import tcpportping
import time
i = 0
while i < 5:
t = tcpportping.tcpping('www.baidu.com', 80, 1000)
if t < 0:
print "time out"
else:
print t
time.sleep(0.5)
i += 1
The result of the port ping is implemented by executing the python code, and from the test results, the program's execution is almost identical to a normal ping.