sockets-file system sockets (AFX_UNIX)

[root@localhost chapter15]# cat server1.c 
/*  Make the necessary includes and set up the variables.  */

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/un.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
    int server_sockfd, client_sockfd;
    int server_len, client_len;
    struct sockaddr_un server_address;
    struct sockaddr_un client_address;

/*  Remove any old socket and create an unnamed socket for the server.  */

    unlink("server_socket");
    server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);

/*  Name the socket.  */

    server_address.sun_family = AF_UNIX;
    strcpy(server_address.sun_path, "server_socket"); //socket name is "server_socket"
    server_len = sizeof(server_address);
    bind(server_sockfd, (struct sockaddr *)&server_address, server_len);

/*  Create a connection queue and wait for clients.  */
        printf("1\n");
    listen(server_sockfd, 2);
        printf("2\n");
    while(1) {
        char ch;
        printf("3\n");
        printf("server waiting\n");

/*  Accept a connection.  */

        client_len = sizeof(client_address);
	//sleep(30);
        client_sockfd = accept(server_sockfd, 
            (struct sockaddr *)&client_address, &client_len);//may block
        printf("4\n");

/*  We can now read/write to client on client_sockfd.  */
	//sleep(3);
printf("before server read\n");
        read(client_sockfd, &ch, 1);
printf("after server read\n");
        ch++;
printf("before server write\n");
        write(client_sockfd, &ch, 1);
printf("after server write\n");
        close(client_sockfd);
    }
}

[root@localhost chapter15]# 
[root@localhost chapter15]# cat client1.c 
/*  Make the necessary includes and set up the variables.  */

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/un.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
    int sockfd;
    int len;
    struct sockaddr_un address;
    int result;
    char ch = 'A';

/*  Create a socket for the client.  */

    sockfd = socket(AF_UNIX, SOCK_STREAM, 0);

/*  Name the socket, as agreed with the server.  */

    address.sun_family = AF_UNIX;
    strcpy(address.sun_path, "server_socket");
//server name is "server_socket",the same as in server.c
    len = sizeof(address);

/*  Now connect our socket to the server's socket.  */

    result = connect(sockfd, (struct sockaddr *)&address, len); //当服务器队列满时,将会阻塞在此
    if(result == -1) {
        perror("oops: client1");
        exit(1);
    }

/*  We can now read/write via sockfd.  */
printf("before client write\n");
    write(sockfd, &ch, 1);
printf("after client write\n");
printf("before client read\n");
    read(sockfd, &ch, 1);
printf("after client read\n");
    printf("char from server = %c\n", ch);
    close(sockfd);
    exit(0);
}
[root@localhost chapter15]# 

[root@localhost chapter15]# ./server1&
[3] 11579
[root@localhost chapter15]# 1
2
3
server waiting
./client1
4
before server read
before client write
after server read
before server write
after server write
3
server waiting
after client write
before client read
after client read
char from server = B

服务器执行    bind(server_sockfd, (struct sockaddr *)&server_address, server_len);
时,会在当前目录下创建一个socket文件
srwxr-xr-x. 1 root root      0 Aug 28 12:18 server_socket
而    listen(server_sockfd, 2);
只不过是创建一个可以容纳2个请求者的监听队列,并不是执行监听
监听并且接受连接的任务落在accept身上
    client_sockfd = accept(server_sockfd,(struct sockaddr *)&client_address, &client_len);
当没有客户端连接请求时,服务器会阻塞在accept处
当有连接请求是,accept会创建一个与原有的命名套接字不同的新套接字,无名,这个
新套接字只用于与这个特定的客户进行通信
而原有的命名套接字则被保留下来继续处理来自其他客户的连接

也可看出,
服务器端read若执行在在客户端write之前,则服务器自动阻塞
客户端read若执行在服务器端write之前,则客户自动阻塞
即read必须在对方write之后才能顺利返回,否则阻塞
他们就是这样一唱一和勾结而同步操作的。

服务器运行在后台while,若多个client一起来临,则按照先后顺序被装进请求队列
服务器每一个while从队列里面仅拎出一个client处理掉
...
由于队列的存在,使得多个请求可以同时请求成功,即多个客户connect均可立即响应而不会阻塞,从而每个client只要连接上立即就能writer socket
但即使这样,由于服务器进程只有一个,也只能一个一个的从队列里面拿出socket处理,
如果某个socket的数据量很大,就需要不少时间,则后面排队的client就会抱怨怎么我的请求还没有处理哪

这样可以为每个连接创建一个线程/进程去执行之。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值