您的位置:首页 > 其它

关于使用UDP套接字进行本地进程通信

2014-07-26 12:34 260 查看
1、linux中进程间的通信可以使用套接字的方式

2、套接字的方式即将套接字的目的地设为“127.0.0.1:port”。以发包的形式将数据传输到本地的某个进程

3、套接字的方式可以选择UDP也可以选择TCP。UDP是不可靠连接,包头中只有源端口,目的端口,UDP长度以及UDP的校验和。传输层协议的校验和是需要对整个数据包进行校验的,具体可以查阅UDP协议和TCP协议头部的解释。

4、另外在<<TCP/IP详解 卷二:实现>>中文版P606页图23-3中,给出了接收缓存的默认大小是41600字节。那么说明一个问题:因为我们知道UDP协议只是尽可能的将数据报发送到目的地,没有重传机制。所以如果发送进程的发送速度太快,使得接收缓存没有能够及时腾出新的空间给新到的数据包,就会导致丢失数据。如果是这样的话,使用UDP套接字似乎不能够完成进程间的通信。

5、不过,还是需要实验证明:

实验设计:使用UDP套接字,本地的一个发送数据的进程将一个文件(srcFile)传输到本地的另一个接收进程。接收进程收到数据之后将其写入到另外一个文件(dstFile)中。比较这两个文件的大小

实验环境:一台4核的笔记本,内存大小为8G。原始文件(srcFile)的大小:4.18GB

实验结果:dstFile的大小为:3.17GB。可见使用UDP方式完成进程间通信,有可能会导致数据的丢失。

实验所用源码如下:(UDP套接字编写的一组简单的收发数据的进程)

接收进程:

#include

#include

#include

#include

#include

#include

int port = 9870;

void main(){

int socket_ser;

char buf[1024];

struct sockaddr_in address;

bzero(&address, sizeof(address));

address.sin_family = AF_INET;

address.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY代表

address.sin_port = htons(port);

socket_ser = socket(AF_INET, SOCK_DGRAM, 0);

bind(socket_ser, (struct sockaddr*)&address, sizeof(address));

FILE *fd = fopen("/dstFile", "wb");

int num = 0;

int add_len = sizeof(address);

while(1){

num = recvfrom(socket_ser, buf, sizeof(buf), 0, (struct socketaddr*)&address, &add_len);

fwrite(buf, sizeof(char), num, fd);

if(num < 1024) break;

}

fclose(fd);

close(socket_ser);

return ;

}

发送进程:

#include

#include

#include

#include

#include

#include

int port = 9870;

void main(){

int socket_cli;

char buf[1024];

struct sockaddr_in address;

bzero(&address, sizeof(address));

address.sin_family = AF_INET;

address.sin_addr.s_addr = inet_addr("127.0.0.1");

address.sin_port = htons(port);

socket_cli = socket(AF_INET, SOCK_DGRAM, 0);

FILE *fd = fopen("/srcFile", "rb");

int n = 0;

while((n = fread(buf, sizeof(char), 1024, fd)) >= 0){

sendto(socket_cli, buf, sizeof(buf), 0, (struct sockaddr*)&address, sizeof(address));

if(n < 1024) break;

}

fclose(fd);

close(socket_cli);

return ;

}

INADDR_ANY就是指定地址为0.0.0.0的地址,这个地址事实上表示不确定地址,或“所有地址”、“任意地址”。 一般来说,在各个系统中均定义成为0值。

例如MontiVista Linux中在/usr/include/netinet/in.h定义为:

/* Address to accept any incoming messages. */

#define INADDR_ANY ((in_addr_t) 0x00000000)

一般情况下,如果你要建立网络服务器应用程序,则你要通知服务器操作系统:请在某地址
xxx.xxx.xxx.xxx上的某端口 yyyy上进行侦听,并且把侦听到的数据包发送给我。这个过程,你是通过bind()系统调用完成的。——也就是说,你的程序要绑定服务器的某地址,或者说:把服务器的某地址上的某端口占为已用。服务器操作系统可以给你这个指定的地址,也可以不给你。

如果你的服务器有多个网卡(每个网卡上有不同的IP地址),而你的服务(不管是在udp端口上侦听,还是在tcp端口上侦听),出于某种原因:可能是你的服务器操作系统可能随时增减IP地址,也有可能是为了省去确定服务器上有什么网络端口网卡)的麻烦
—— 可以要在调用bind()的时候,告诉操作系统:“我需要在 yyyy 端口上侦听,所有发送到服务器的这个端口,不管是哪个网卡/哪个IP地址接收到的数据,都是我处理的。”这时候,服务器程序则在0.0.0.0这个地址上进行侦听。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: