tcp socket, select tells writable, but write() blocks
Question: I wrote a little tcp socket server program, using select() to check if a
client socket is writable. If the client is writable, I will write data to it.

The client is written in Python, for testing only, it connect to the server,
and never read from the connect.

The result is, server write() finally blocks.

**Server(C):**

    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <errno.h>
    #include <arpa/inet.h>
    #include <netinet/tcp.h>
    #include <sys/select.h>
    
    int main(int argc, char **argv){
        int serv_sock;
        struct sockaddr_in addr;
        const char *ip = "0.0.0.0";
        int opt = 1;
        int port = 7000;
        if(argc > 2){
            port = atoi(argv[1]);
        }
    
        bzero(&addr, sizeof(addr));
        addr.sin_family = AF_INET;
        addr.sin_port = htons((short)port);
        inet_pton(AF_INET, ip, &addr.sin_addr);
    
        serv_sock = socket(AF_INET, SOCK_STREAM, 0);
        setsockopt(serv_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
        bind(serv_sock, (struct sockaddr *)&addr, sizeof(addr));
        listen(serv_sock, 1024);
    
        printf("server listen on port: %d\n", port);
    
        int sock = accept(serv_sock, NULL, NULL);
        printf("accepted\n");
    
        while(1){
            fd_set w_set;
            FD_ZERO(&w_set);
            int maxfd = sock;
            FD_SET(sock, &w_set);
            int ret = select(maxfd + 1, NULL, &w_set, NULL, NULL);
            if(ret < 0){
                if(errno == EINTR){
                    continue;
                }else{
                    printf("select error! %s\n", strerror(errno));
                    exit(0);
                }
            }
            char buf[128 * 1024];
            if(FD_ISSET(sock, &w_set)){
                printf("write begin\n");
                int n = write(sock, buf, sizeof(buf));
                printf("write %d\n", n);
            }
        }
    
        return 0;
    }
    

**Client(Python):**

    
    
    import socket
    s = socket.socket()
    s.connect(('127.0.0.1', 7000))
    

**Output:**

    
    
    $ gcc a.c; ./a.out 
    server listen on port: 7000
    accepted
    write begin
    write 131072
    write begin
    write 131072
    write begin
    write 131072
    write begin
    write 131072
    write begin
    write 131072
    write begin
    

My qustion is: **why would write() operation blocks even if select tells
writable?** The manual of select() says:

> A file descriptor is considered ready if it is possible to perform the
> corresponding I/O operation (e.g., read(2)) without blocking.


Answer: Select() doesnt know how many bytes you are going to try to write, it only
knows that the socket's outgoing-data buffer isn't full.

If you want write() not to block, set the socket to non-blocking mode.

