逐步实现TCP服务端Step01:原始阶段

原始阶段:服务端一次只受理一个客户,在对当前客户服务期间,其他客户没机会连进来。这个阶段的服务端做的事情非常简单,就是将收到的字节原封不动地返回去。

由于没有定义消息格式,现阶段不需要实现专用的client程序,测试的时候直接使用telnet或者netcat就可以:

telnet ip port
nc ip port

这里及后续的实现代码都是比较粗糙的,只是为了说明问题,没有做太多的考虑。程序中也没有日志输出,只是个别要关注的地方做了标准输出。对于错误处理,程序中只要出现错误,就直接返回,结束运行。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <unistd.h>
#include <sys/types.h>  
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main(int argc, char**argv)
{
    if (argc != 2) {
        std::clog << "Usage: " 
            << argv[0] << " port" << std::endl;
        return 0;
    }
    int svr_sock, cli_sock;
    sockaddr_in svr_addr, cli_addr;
    if ((svr_sock = socket(AF_INET, 
        SOCK_STREAM, 0)) < 0) {
        return 1;
    }
    memset(&svr_addr, 0, sizeof(svr_addr));
    svr_addr.sin_family = AF_INET;
    svr_addr.sin_port = htons(atoi(argv[1]));
    svr_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    if (bind(svr_sock, 
        (const sockaddr*)&svr_addr, 
        sizeof(svr_addr)) < 0) {
        return 1;
    }
    if (listen(svr_sock, 4) < 0) {
        return 1;
    }
    while (1) {
        memset(&cli_addr, 0, sizeof(cli_addr));
        socklen_t addr_len = sizeof(cli_addr);
        if ((cli_sock = accept(svr_sock, 
            (sockaddr*)&cli_addr, &addr_len)) < 0) {
            return 1;
        }
        unsigned char buf[128] = {0};
        int recv_bytes_cnt = 0;
        while (1) {
            if ((recv_bytes_cnt = recv(cli_sock, 
                buf, sizeof(buf), 0)) < 0) {
                return 1;
            }
            if (0 == recv_bytes_cnt) {
                std::clog << "cli close!" << std::endl;
                break;
            }
            if (send(cli_sock, buf, recv_bytes_cnt, 0) < 0) {
                return 1;
            }
        }
        close(cli_sock);
    }
    return 0;
}

<==  index  ==>