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调试之,客户端截图:


  • 相关阅读:
    use imagination
    tar
    简单抓取安居客房产数据,并保存到Oracle数据库
    svn的安装(整合apache、ldap)包括错误解决post commit FS processing had error
    SVN安装中遇到的问题
    Linux环境源码编译安装SVN
    [转]SVN安装问题The Apache Portable Runtime (APR) library cannot be found
    深入浅出数据分析-脑图
    Python3.5在Windows 7下连接ORACLE数据库
    Python3.5之TuShare
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/2989621.html
Copyright © 2011-2022 走看看