C++网络编程——实现一个简单的echo服务器

在前面讲完了服务器从建立套接字、绑定、监听和提取,以及客户端的连接,我们已经可以动手实现一个简单的镜像服务器。

错误处理

在那之前,我们先封装一个错误处理函数 errif

可以定义一个uitl.cpp放里面,需要的地方引用即可

util.h

#ifndef UTIL_H
#define UTIL_H
​
void errif(bool, const char*);
​
#endif

util.cpp

#include "util.h"
#include <stdio.h>
#include <stdlib.h>
​
void errif(bool condition, const char *errmsg){
    if(condition){
        perror(errmsg);
        exit(EXIT_FAILURE);
    }
}

服务端代码

server.cpp

#include<stdio.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<string.h>
#include<unistd.h>
#include "util.h"
​
int main(){
    int socketfd = socket(AF_INET,SOCK_STREAM,0);
    errif(sockfd == -1 "socket crete error");
    
    struct sockaddr_in serv_addr;
    bzero(&serv_addr,sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    serv_addr.sin_port = htons(8888);
    
    errif(bind(sockfd,(sockaddr*)&serv_addr,sizeof(serv_addr)) == -1,"socket bind error");
    errif(listen(sockfd,SOMAXCONN) == -1,"socket listen error");
    
    struct sockaddr_in clnt_addr;
    socklen_t clnt_addr_len = sizeof(clnt_addr);
    bzero(&clnt_addr,sizeof(clnt_addr));
    int clnt_sockfd = accept(sockfd,(sockaddr*)&clnt_addr,&clnt_addr_len);
    errif(clnt_sockfd == -1,"socket accept error");
    printf("new client fd %d! IP:%s Port:%d\n",clnt_sockfd,inet_ntoa(clnt_addr.sin_addr),ntohs(clnt_addr.sin_port));
    //读写
    while (true) {
        char buf[1024];
        bzero(&buf,sizeof(buf));
        ssize_t read_bytes = read(clnt_sockfd,buf,sizeof(buf));
        if(read_bytes > 0){
            printf("message from client fd %d:%s",clnt_sockfd,buf);
            write(clnt_sockfd,buf,sizeof(buf));
        }else if(read_bytes == 0){
            printf("client fd %d disconnected\n",clnt_sockfd);
            close(clnt_sockfd);
            break;
        }
        else{
            close(clnt_sockfd);
            errif(true,"socket read error");
        }
    }
    close(sockfd);
    return 0;
}

客户端代码

client.cpp

#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include "util.h"
​
int main(){
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    errif(sockfd == -1 "socket create error");
    
    struct sockaddr_in serv_addr;
    bzero(&serv_addr,sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    serv_addr.sin_port = htons(8888);
    
    errif(connect(sockfd,(sockaddr*)&serv_addr,sizeof(serv_addr)) == -1,"socket connect error");
    
    while(true){
        char buf[1024];
        bzero(&buf,sizeof(buf));
        scanf("%s",buf);
        ssize_t write_bytes = write(sockfd,buf,sizeof(buf));
        if(write_bytes == -1){
            printf("socket already disconnected, can't write any more!\n");
            break;
        }
        bzero(&buf,sizeof(buf));
        ssize_t read_bytes = read(sockfd,buf,sizeof(buf));
        if(read_bytes > 0){
            printf("message from server:%s",buf);
        }else if(read_bytes == 0){
            printf("server socket disconnected\n");
            break;
        }
        else{
            errif(true, "socket read error");
            break;
        }
    }
    close(sockfd);
    return 0;
}

上一篇:.net 框架基础(三) 其他——随机数Random、Guid 结构体、常用类


下一篇:MySQL目录和文件