19.unix域协议与TCP UDP不同之处

之前说过一些区别,但基本对我们编程来说没有太多影响,但以下几个方面是需要注意到的。

1.当调用connect时候,需要注意的是打开文件的权限。只有进程能够有足够的权限,connect才会能够返回。

2.当发现监听套接口的队列满的时候,会立刻返回一个ECONNREFUSED错误。而之前的TCP不会返回错误,TCP客户端会认为是SYN包丢失而多次向服务器发送SYN。

3.在UNIX域协议中,如果采用SOCK_DGRAM方式通信,在未绑定的套接口上不会捆绑一个路径名(UDP不同,没有执行bind的客户端,系统会自动分配一个地址和端口号),当然,如果只是发送数据,仍然可以成功,但是当想返回数据的时候,数据是无法返回,如果想得到返回数据必须为其捆绑一个路径名。如下面这端程序

服务器

#include "/programe/net/head.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "sys/select.h"
#include "sys/un.h"

int main(int argc, char ** argv) {
        int sockfd;
        socklen_t len;
        struct sockaddr_un addr, client_addr;
        char buf[101];

        sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0);

        bzero(&addr, sizeof(struct sockaddr_un));
        addr.sun_family = AF_LOCAL;

        strncpy(addr.sun_path, argv[1], sizeof(addr.sun_path) - 1);
        unlink(argv[1]);
        int flag = bind(sockfd, (struct sockaddr *)&addr, SUN_LEN(&addr));
        if(flag == -1) {
                printf("bind socket error\n");
                exit(1);
        }
        len = sizeof(client_addr);
        int n = recvfrom(sockfd, buf, 100, 0, (struct sockaddr *)&client_addr, &len);
        printf("bound name = %s\n", client_addr.sun_path);
        buf[n] = '\0';
        printf("get message:%s", buf);
        n = sendto(sockfd, buf, n, 0, (struct sockaddr *)&client_addr, len);
        close(sockfd);
}

客户端

#include "/programe/net/head.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "sys/select.h"
#include "sys/un.h"

int main(int argc, char ** argv) {
        int sockfd;
        socklen_t len;
        struct sockaddr_un addr;
        struct sockaddr_un my_addr;

        sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
        bzero(&addr, sizeof(struct sockaddr_un));
        addr.sun_family = AF_LOCAL;
        strncpy(addr.sun_path, argv[1], sizeof(addr.sun_path) - 1);

        bzero(&my_addr, sizeof(struct sockaddr_un));
        my_addr.sun_family = AF_LOCAL;
        strncpy(my_addr.sun_path, argv[2], sizeof(my_addr.sun_path) - 1);

        unlink(argv[2]);
        bind(sockfd, (struct sockaddr *)&my_addr, SUN_LEN(&my_addr)); //这一步如果是想得到从服务器的返回数据则必须做,不然无法得到返回数据,当然如果不需要返回只是发送则无需这一步。

        char buf[101];
        char buf1[101];
        int n = read(0, buf, 100);
        len = sizeof(addr);
        int m = sendto(sockfd, buf, n, 0, (struct sockaddr *)&addr, len);
        int c = recvfrom(sockfd, buf1, 100, 0, NULL, NULL);
        buf1[c] = '\0';
        printf("get message:%s", buf1);
        close(sockfd);
        exit(0);
}

猜你喜欢

转载自memorymyann.iteye.com/blog/650355