使用fork()編寫socket

服務端

//
//  Tcp_server.cpp
//  Cpp
//
//  Created by JH on 2020/4/5.
//  Copyright © 2020 JH. All rights reserved.
//

#include <stdio.h>
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>


#define PORT 8111
#define MESSAGE_LEN 1024

int main(int argc,char * argv[]){
    
    int ret = -1;
    int socket_fd ,accept_fd;
    int on =1;
    int backlog = 10;
    
    pid_t pid;
    
    char in_buff[MESSAGE_LEN] ={0};
    
    struct sockaddr_in localaddr,remoteaddr;
    
    socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    
    if (socket_fd == -1) {
        exit(-1);
    }
    
    ret = setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
    
    if (ret == -1) {
        std:: cout << "set option failed" << std::endl;
        exit(-1);
    }
    localaddr.sin_family = AF_INET;
    localaddr.sin_port = PORT;
    localaddr.sin_addr.s_addr = INADDR_ANY;
    bzero(&(localaddr.sin_zero), 8);
    
    ret = bind(socket_fd, (struct sockaddr *)&localaddr, sizeof(struct sockaddr));
    
    if (ret == -1) {
        std:: cout << "set bind failed" << std::endl;
        exit(-1);
    }
    
    ret = listen(socket_fd, backlog);
    if (ret == -1) {
        std:: cout << "set listen failed" << std::endl;
        exit(-1);
    }
    
//    if (daemon(0, 0) == -1) {
//        std::cout <<"後臺出錯" << std::endl;
//        exit(-1);
//    }
//    
    ssize_t size;
    for (; ; ) {
        socklen_t addr_len = sizeof(struct sockaddr);
        //接收客戶端的socket
        accept_fd = accept(socket_fd, (struct sockaddr *)& remoteaddr, &addr_len);
        
        pid =fork();
        if (pid == 0) { // 等於0表示子進程,缺點:資源被長期佔用,分配子進程花費時間長
            for (; ; ) {
                
                memset(in_buff, 0, MESSAGE_LEN);
                
                   size = recv(accept_fd, (void *) in_buff, MESSAGE_LEN, 0);
                   
                   if (size < 0) {
                       break;
                   }
                   std:: cout <<"recv : " <<in_buff << std::endl;
                   send(accept_fd, (void *)in_buff, MESSAGE_LEN, 0);
               }
            
                 close(accept_fd);
        }
        

    }
//    close(socket_fd);
    
    return 0;
}

客戶端代碼

//
//  Tcp_Client.cpp
//  Cpp
//
//  Created by JH on 2020/4/7.
//  Copyright © 2020 JH. All rights reserved.
//

#include <stdio.h>
#include <sys/socket.h>
#include  <netinet/in.h>
#include <iostream>
#include <unistd.h>
#include <arpa/inet.h>

#define PORT 8111

#define MESSAEG_LEN 1024

int main(int argc,char *argv[]){
    
    int socket_fd;
    
    int ret;
    
    char sendbuf[MESSAEG_LEN] ={0};
    char recvbuf[MESSAEG_LEN] ={0};
    struct sockaddr_in serveraddr;
    
    ssize_t status;
    
    socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    
    if (socket_fd == -1) {
        std::cout<< "failed to create socekt" << std::endl;
        exit(-1);
    }
    
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = PORT;
    serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    
    socklen_t size =sizeof(struct sockaddr);
    
    ret = connect(socket_fd, (struct sockaddr*)&serveraddr, size);
    
    if (ret < 0) {
        std:: cout << "failed to connect server !" <<std::endl;
        exit(-1);
    }
    
    while (1) {
        //清空sendbuf
        memset(sendbuf, 0, MESSAEG_LEN);
        
        gets(sendbuf);
        status = send(socket_fd, sendbuf, strlen(sendbuf), 0);
        if (status < 0) {
            std:: cout << "failed to send message !" <<std::endl;
            exit(-1);
            
        }
        
        if (strcmp(sendbuf, "quit")==0) {
            break;
        }
        
        
        status = recv(socket_fd, recvbuf, MESSAEG_LEN, 0);
        
        recvbuf[status] = '\0';
        
        std:: cout<< "recv:"<<recvbuf <<std::endl;
    }
    
    close(socket_fd);
    
    return 0;
}

服務端輸入命令

C++ -g -o tcp_server Tcp_server.cpp

./tcp_server

使用fork()可以接收多個客戶端發送來的消息。

fork的缺點:資源被長期佔用,分配子進程花費時間長

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章