zoukankan      html  css  js  c++  java
  • 网络程序为什么要处理SIGPIPE

             根据unix环境高级编程一书,我们知道管道在读端关闭时,写端继续写会引发SIGPIPE,而在网络(socket)连接的情况下,

    如果接收端在发送端正在写的情况下关闭,发送端也会触发SIGPIPE,如果不处理该信号,那么程序就会崩溃。

            测试代码:

            服务端:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <string.h>
    #include <errno.h>
    #include <fcntl.h>
    #include <sys/socket.h> 
    #include <netinet/in.h> 
    
    #define BUFFER_SIZE 8192
    
    char buffer[BUFFER_SIZE];
    
    void child_handle_send_recieve(int *client_fd);
    int main() {
    	int rc;
    	int socket_fd;
    
    	int client_fd;
    	int reuse = 1;
    
    	socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    	if (socket_fd < 0) {
    		perror("socket initial error");
    	}
    
    	struct sockaddr_in addr;
    	addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    	addr.sin_family = AF_INET;
    	addr.sin_port = htons(1989);
    
    	rc = setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
    	if (rc < 0) {
    		perror("set socket failed.");
    	}
    	rc = bind(socket_fd, (struct sockaddr*) &addr, sizeof(addr));
    	if (rc < 0) {
    		perror("bind failed");
    	}
    
    	rc = listen(socket_fd, 5);
    	if (rc < 0) {
    		perror("listen failed");
    	}
    
    	while (1) {
    		client_fd = rc = accept(socket_fd, NULL, 0);
    		if (rc < 0) {
    			perror("accept failed");
    		}
    		int fork_rt;
    		if ((fork_rt = fork()) < 0) {
    			perror("fork error");
    		} else if (fork_rt > 0) { // parent
    			close(client_fd);
    		} else { // child process.
    			close(socket_fd);
    			child_handle_send_recieve(&client_fd);
    		}
    	}
    	close(socket_fd);
    	return 0;
    }
    
    void child_handle_send_recieve(int *client) {
    	int client_fd = *client;
    	int rc;
    
        memset(buffer, '\0', sizeof(buffer));
    	rc = recv(client_fd, buffer, BUFFER_SIZE, 0);
    	if (rc < 0) {
    		perror("receive failed");
    	}
    	printf("received:%s\n", buffer);
    	
        // close it now.
    	close(client_fd);
    	exit(0);
    }
    

               客户端:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/ioctl.h>
    #include <sys/stat.h>
    #include <arpa/inet.h>
    #include <fcntl.h>
    
    #define BUFFER_SIZE 8192
    
    int main(){
    
        int socket_fd;
        struct sockaddr_in addr;
        char buf[BUFFER_SIZE];
        int rc;
        socket_fd = socket(AF_INET,SOCK_STREAM,0);
    
        addr.sin_addr.s_addr = inet_addr("127.0.0.1");
        addr.sin_family = AF_INET;
        addr.sin_port = htons(1989);
    
        rc = connect(socket_fd, (struct sockaddr*)&addr, sizeof(addr));
        if(rc < 0){
            perror("connect failed");
        }
    
        bzero(buf, sizeof(buf));
        strncpy(buf,"hello man.",11);
        while(1){
            rc = send(socket_fd, buf,strlen(buf),0);
            if(rc < 0){
                perror("send failed");
            }
        }
    
        // never can print.
        printf("It's ok here????");
        return 0;
    }
    


            用gdb调试之,客户端截图:


  • 相关阅读:
    Android开发之Sqlite的使用
    ZOJ 3607 Lazier Salesgirl
    ZOJ 3769 Diablo III
    ZOJ 2856 Happy Life
    Ural 1119 Metro
    Ural 1146 Maximum Sum
    HDU 1003 Max Sum
    HDU 1160 FatMouse's Speed
    Ural 1073 Square Country
    Ural 1260 Nudnik Photographer
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/2989621.html
Copyright © 2011-2022 走看看