├── .idea
├── NetworkProgramming.iml
├── encodings.xml
├── misc.xml
├── modules.xml
└── vcs.xml
├── 01mqopen.cpp
├── 01shmopen.cpp
├── 02myunlink.cpp
├── 02shmunlink.cpp
├── 03mqgetattr.cpp
├── 03shmwrite.cpp
├── 04mqsend.cpp
├── 04shmreceive.cpp
├── 05mqreceive.cpp
├── 06mqnotify.cpp
├── CMakeLists.txt
├── README.md
├── condtest.cpp
├── conntest.cpp
├── echocli.cpp
├── echocli2.cpp
├── echocli3.cpp
├── echocli4.cpp
├── echocli5.cpp
├── echocli6.cpp
├── echocli7.cpp
├── echosrv.cpp
├── echosrv2.cpp
├── echosrv3.cpp
├── echosrv4.cpp
├── echosrv5.cpp
├── echosrv6.cpp
├── echosrv7.cpp
├── epollsrv.cpp
├── gethostbyname_test.cpp
├── main.cpp
├── mmap_recv.cpp
├── mmap_send.cpp
├── msg_recv.cpp
├── msg_send.cpp
├── msgcli.cpp
├── msgctl01.cpp
├── msgctl02.cpp
├── msgget.cpp
├── msgsrv.cpp
├── p2pcli.cpp
├── p2pserv.cpp
├── pctest.cpp
├── pollsrv.cpp
├── sem.cpp
├── sem02.cpp
├── sem03.cpp
├── shmfifo
├── CMakeLists.txt
├── shmfifo.cpp
├── shmfifo.h
├── shmfifo_destroy.cpp
├── shmfifo_recv.cpp
└── shmfifo_send.cpp
├── shmread.cpp
├── shmwrite.cpp
├── sockpair.cpp
├── sockpair02.cpp
├── thread.cpp
├── thread_create.cpp
├── threadechosrv.cpp
├── threadpool
├── CMakeLists.txt
├── condition.cpp
├── condition.h
├── test.cpp
├── threadpool.cpp
└── threadpool.h
├── udpchat
├── CMakeLists.txt
├── Pub.h
├── UdpChatCli.cpp
└── UdpChatSrv.cpp
├── udpcli.cpp
├── udpmulclt.cpp
├── udpmulsrv.cpp
├── udpsrv.cpp
├── unixcli.cpp
└── unixsrv.cpp
/.idea/NetworkProgramming.iml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/01mqopen.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-14.
3 | //
4 |
5 | // p34 poxis消息队列
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include /* For O_* constants */
14 | #include /* For mode constants */
15 | #include
16 |
17 | using namespace std;
18 |
19 | #define ERR_EXIT(m) \
20 | do \
21 | { \
22 | perror(m); \
23 | exit(EXIT_FAILURE); \
24 | } while (0);
25 |
26 | int main(int argc, char** argv)
27 | {
28 | // mq_overview
29 | mqd_t mqid = mq_open("/abc", O_CREAT | O_RDWR, 0666, NULL);
30 | if (mqid == ((mqd_t) -1))
31 | {
32 | ERR_EXIT("mq_open");
33 | }
34 |
35 | printf("mqopen success\n");
36 | mq_close(mqid);
37 | printf("mqclose success\n");
38 | return 0;
39 | }
--------------------------------------------------------------------------------
/01shmopen.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-14.
3 | //
4 |
5 | // p35 poxis共享内存
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include /* For O_* constants */
14 | #include /* For mode constants */
15 | #include
16 | #include
17 |
18 | using namespace std;
19 |
20 | #define ERR_EXIT(m) \
21 | do \
22 | { \
23 | perror(m); \
24 | exit(EXIT_FAILURE); \
25 | } while (0);
26 |
27 | struct student
28 | {
29 | char name[32];
30 | int age;
31 | };
32 |
33 | int main(int argc, char** argv)
34 | {
35 | int shmid;
36 | shmid = shm_open("/xyz", O_CREAT | O_RDWR, 0666);
37 | //shmid = shm_open("/xyz", O_RDWR, S_IRUSR);
38 | if (shmid == -1)
39 | {
40 | ERR_EXIT("shmid");
41 | }
42 | printf("shmopen success\n");
43 |
44 | student stu;
45 | strcpy(stu.name , "hello");
46 | stu.age = 20;
47 |
48 | if (ftruncate(shmid, sizeof(stu)) == -1)
49 | {
50 | ERR_EXIT("ftruncate");
51 | }
52 | printf("truncate succ\n");
53 |
54 | struct stat buf;
55 | if (fstat(shmid, &buf) == -1)
56 | {
57 | ERR_EXIT("fstat");
58 | }
59 |
60 | printf("mode: %o, size: %ld\n", buf.st_mode & 07777, buf.st_size);
61 |
62 | close(shmid);
63 |
64 | return 0;
65 | }
--------------------------------------------------------------------------------
/02myunlink.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-14.
3 | //
4 |
5 | // p34 poxis消息队列
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include /* For O_* constants */
14 | #include /* For mode constants */
15 | #include
16 |
17 | using namespace std;
18 |
19 | #define ERR_EXIT(m) \
20 | do \
21 | { \
22 | perror(m); \
23 | exit(EXIT_FAILURE); \
24 | } while (0);
25 |
26 | int main(int argc, char** argv)
27 | {
28 | // mq_overview
29 | mqd_t mqid = mq_open("/abc", O_RDWR);
30 | if (mqid == ((mqd_t) -1))
31 | {
32 | ERR_EXIT("mq_open");
33 | }
34 |
35 | printf("mqopen success\n");
36 |
37 | if (mq_unlink("/abc") == -1)
38 | {
39 | ERR_EXIT("mq_unlink");
40 | }
41 |
42 | printf("mqunlink success\n");
43 |
44 | mq_close(mqid);
45 |
46 | return 0;
47 | }
--------------------------------------------------------------------------------
/02shmunlink.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-14.
3 | //
4 |
5 | // p35 poxis共享内存
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include /* For O_* constants */
14 | #include /* For mode constants */
15 | #include
16 | #include
17 |
18 | using namespace std;
19 |
20 | #define ERR_EXIT(m) \
21 | do \
22 | { \
23 | perror(m); \
24 | exit(EXIT_FAILURE); \
25 | } while (0);
26 |
27 | struct student
28 | {
29 | char name[32];
30 | int age;
31 | };
32 |
33 | int main(int argc, char** argv)
34 | {
35 | int shmid;
36 | shmid = shm_open("/xyz", O_CREAT | O_RDWR, 0666);
37 | //shmid = shm_open("/xyz", O_RDWR, S_IRUSR);
38 | if (shmid == -1)
39 | {
40 | ERR_EXIT("shmid");
41 | }
42 | printf("shmopen success\n");
43 |
44 | student stu;
45 | strcpy(stu.name , "hello");
46 | stu.age = 20;
47 |
48 | if (ftruncate(shmid, sizeof(stu)) == -1)
49 | {
50 | ERR_EXIT("ftruncate");
51 | }
52 | printf("truncate succ\n");
53 |
54 | struct stat buf;
55 | if (fstat(shmid, &buf) == -1)
56 | {
57 | ERR_EXIT("fstat");
58 | }
59 |
60 | printf("mode: %o, size: %ld\n", buf.st_mode & 07777, buf.st_size);
61 |
62 | close(shmid);
63 | if (shm_unlink("/xyz") == -1)
64 | {
65 | ERR_EXIT("shmunlink");
66 | }
67 | printf("shm_unlink succ\n");
68 |
69 |
70 | return 0;
71 | }
--------------------------------------------------------------------------------
/03mqgetattr.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-14.
3 | //
4 |
5 | // p34 poxis消息队列
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include /* For O_* constants */
14 | #include /* For mode constants */
15 | #include
16 |
17 | using namespace std;
18 |
19 | #define ERR_EXIT(m) \
20 | do \
21 | { \
22 | perror(m); \
23 | exit(EXIT_FAILURE); \
24 | } while (0);
25 |
26 | int main(int argc, char** argv)
27 | {
28 | // mq_overview
29 | mqd_t mqid = mq_open("/abc", O_RDONLY);
30 | if (mqid == ((mqd_t) -1))
31 | {
32 | ERR_EXIT("mq_open");
33 | }
34 |
35 | //printf("mqopen success\n");
36 |
37 | struct mq_attr attr;
38 |
39 | if (mq_getattr(mqid, &attr) == -1)
40 | {
41 | ERR_EXIT("mq_getattr");
42 | }
43 | printf("max #msg = %ld max #bytes/msg = %ld #currently on queue = %ld\n", attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs);
44 |
45 | mq_close(mqid);
46 |
47 | return 0;
48 | }
--------------------------------------------------------------------------------
/03shmwrite.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-14.
3 | //
4 |
5 | // p35 poxis共享内存
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include /* For O_* constants */
14 | #include /* For mode constants */
15 | #include
16 | #include
17 |
18 | using namespace std;
19 |
20 | #define ERR_EXIT(m) \
21 | do \
22 | { \
23 | perror(m); \
24 | exit(EXIT_FAILURE); \
25 | } while (0);
26 |
27 | struct student
28 | {
29 | char name[32];
30 | int age;
31 | };
32 |
33 | int main(int argc, char** argv)
34 | {
35 | int shmid;
36 | shmid = shm_open("/xyz", O_CREAT | O_RDWR, 0666);
37 | //shmid = shm_open("/xyz", O_RDWR, S_IRUSR);
38 | if (shmid == -1)
39 | {
40 | ERR_EXIT("shmid");
41 | }
42 | printf("shmopen success\n");
43 |
44 | student* stu;
45 |
46 |
47 | if (ftruncate(shmid, sizeof(stu)) == -1)
48 | {
49 | ERR_EXIT("ftruncate");
50 | }
51 | printf("truncate succ\n");
52 |
53 | struct stat buf;
54 | if (fstat(shmid, &buf) == -1)
55 | {
56 | ERR_EXIT("fstat");
57 | }
58 |
59 | printf("mode: %o, size: %ld\n", buf.st_mode & 07777, buf.st_size);
60 |
61 | stu = (student*)mmap(NULL, buf.st_size, PROT_WRITE, MAP_SHARED, shmid, 0);
62 |
63 | strcpy(stu->name , "hello");
64 | stu->age = 20;
65 |
66 | close(shmid);
67 |
68 | return 0;
69 | }
--------------------------------------------------------------------------------
/04mqsend.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-14.
3 | //
4 |
5 | // p34 poxis消息队列
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include /* For O_* constants */
14 | #include /* For mode constants */
15 | #include
16 |
17 | using namespace std;
18 |
19 | #define ERR_EXIT(m) \
20 | do \
21 | { \
22 | perror(m); \
23 | exit(EXIT_FAILURE); \
24 | } while (0);
25 |
26 | struct student
27 | {
28 | char name[32];
29 | int age;
30 | };
31 |
32 | int main(int argc, char** argv)
33 | {
34 | if (argc != 2)
35 | {
36 | fprintf(stderr, "Usage: %s \n", argv[1]);
37 | }
38 |
39 | // mq_overview
40 | mqd_t mqid = mq_open("/abc", O_WRONLY);
41 | if (mqid == ((mqd_t) -1))
42 | {
43 | ERR_EXIT("mq_open");
44 | }
45 |
46 | //printf("mqopen success\n");
47 | student stu;
48 | strcpy(stu.name, "hello");
49 | stu.age = 20;
50 |
51 | if (mq_send(mqid, (const char*)&stu, sizeof(stu), atoi(argv[1])) == -1)
52 | {
53 | ERR_EXIT("mq_send");
54 | }
55 |
56 | printf("send success\n");
57 | mq_close(mqid);
58 |
59 | return 0;
60 | }
--------------------------------------------------------------------------------
/04shmreceive.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-14.
3 | //
4 |
5 | // p35 poxis共享内存
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include /* For O_* constants */
14 | #include /* For mode constants */
15 | #include
16 | #include
17 |
18 | using namespace std;
19 |
20 | #define ERR_EXIT(m) \
21 | do \
22 | { \
23 | perror(m); \
24 | exit(EXIT_FAILURE); \
25 | } while (0);
26 |
27 | struct student
28 | {
29 | char name[32];
30 | int age;
31 | };
32 |
33 | int main(int argc, char** argv)
34 | {
35 | int shmid;
36 | shmid = shm_open("/xyz", O_CREAT | O_RDWR, 0666);
37 | //shmid = shm_open("/xyz", O_RDWR, S_IRUSR);
38 | if (shmid == -1)
39 | {
40 | ERR_EXIT("shmid");
41 | }
42 | printf("shmopen success\n");
43 |
44 | student* stu;
45 | if (ftruncate(shmid, sizeof(stu)) == -1)
46 | {
47 | ERR_EXIT("ftruncate");
48 | }
49 | printf("truncate succ\n");
50 |
51 | struct stat buf;
52 | if (fstat(shmid, &buf) == -1)
53 | {
54 | ERR_EXIT("fstat");
55 | }
56 |
57 | printf("mode: %o, size: %ld\n", buf.st_mode & 07777, buf.st_size);
58 |
59 | stu = (student*)mmap(NULL, buf.st_size, PROT_READ, MAP_SHARED, shmid, 0);
60 | printf("name: %s, age: %d\n", stu->name, stu->age);
61 |
62 | close(shmid);
63 |
64 | return 0;
65 | }
--------------------------------------------------------------------------------
/05mqreceive.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-14.
3 | //
4 |
5 | // p34 poxis消息队列
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include /* For O_* constants */
14 | #include /* For mode constants */
15 | #include
16 |
17 | using namespace std;
18 |
19 | #define ERR_EXIT(m) \
20 | do \
21 | { \
22 | perror(m); \
23 | exit(EXIT_FAILURE); \
24 | } while (0);
25 |
26 | struct student
27 | {
28 | char name[32];
29 | int age;
30 | };
31 |
32 | int main(int argc, char** argv)
33 | {
34 | // mq_overview
35 | mqd_t mqid = mq_open("/abc", O_RDONLY);
36 | if (mqid == ((mqd_t) -1))
37 | {
38 | ERR_EXIT("mq_open");
39 | }
40 |
41 | //printf("mqopen success\n");
42 |
43 | struct mq_attr attr;
44 |
45 | if (mq_getattr(mqid, &attr) == -1)
46 | {
47 | ERR_EXIT("mq_getattr");
48 | }
49 |
50 | size_t size = attr.mq_msgsize;
51 | student stu;
52 |
53 | if (mq_receive(mqid, (char*)&stu, size, NULL) == -1)
54 | {
55 | ERR_EXIT("mq_receive");
56 | }
57 |
58 | printf("student name = %s, age = %d\n", stu.name, stu.age);
59 | mq_close(mqid);
60 |
61 | return 0;
62 | }
--------------------------------------------------------------------------------
/06mqnotify.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-14.
3 | //
4 |
5 | // p34 poxis消息队列
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include /* For O_* constants */
14 | #include /* For mode constants */
15 | #include
16 | #include
17 |
18 | using namespace std;
19 |
20 | #define ERR_EXIT(m) \
21 | do \
22 | { \
23 | perror(m); \
24 | exit(EXIT_FAILURE); \
25 | } while (0);
26 |
27 | struct student
28 | {
29 | char name[32];
30 | int age;
31 | };
32 |
33 | size_t size;
34 | mqd_t mqid;
35 | struct sigevent sigv;
36 |
37 | void handler(int s)
38 | {
39 | mq_notify(mqid, &sigv);
40 | student stu;
41 |
42 | if (mq_receive(mqid, (char*)&stu, size, NULL) == -1)
43 | {
44 | ERR_EXIT("mq_receive");
45 | }
46 |
47 | printf("student name = %s, age = %d\n", stu.name, stu.age);
48 | }
49 |
50 | int main(int argc, char** argv)
51 | {
52 | // mq_overview
53 | mqid = mq_open("/abc", O_RDONLY);
54 | if (mqid == ((mqd_t) -1))
55 | {
56 | ERR_EXIT("mq_open");
57 | }
58 |
59 | //printf("mqopen success\n");
60 | struct mq_attr attr;
61 | if (mq_getattr(mqid, &attr) == -1)
62 | {
63 | ERR_EXIT("mq_getattr");
64 | }
65 |
66 | size = attr.mq_msgsize;
67 |
68 |
69 | signal(SIGUSR1, handler); //定义一个信号函数,当SIGALRM信号发过来时,执行handler函数
70 |
71 | sigv.sigev_notify = SIGEV_SIGNAL;
72 | sigv.sigev_signo = SIGUSR1;
73 |
74 | mq_notify(mqid, &sigv);
75 |
76 | while (true)
77 | {
78 | pause();
79 | }
80 |
81 | mq_close(mqid);
82 |
83 | return 0;
84 | }
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.5.1)
2 | project(NetworkProgramming)
3 |
4 | set(CMAKE_CXX_STANDARD 14)
5 |
6 | add_executable(NetworkProgramming main.cpp)
7 | add_executable(echosrv echosrv.cpp)
8 | add_executable(echocli echocli.cpp)
9 | add_executable(echosrv2 echosrv2.cpp)
10 | add_executable(echocli2 echocli2.cpp)
11 | add_executable(echosrv3 echosrv3.cpp)
12 | add_executable(echocli3 echocli3.cpp)
13 | add_executable(echosrv4 echosrv4.cpp)
14 | add_executable(echocli4 echocli4.cpp)
15 | add_executable(echosrv5 echosrv5.cpp)
16 | add_executable(echocli5 echocli5.cpp)
17 | add_executable(echosrv6 echosrv6.cpp)
18 | add_executable(echocli6 echocli6.cpp)
19 | add_executable(echosrv7 echosrv7.cpp)
20 | add_executable(echocli7 echocli7.cpp)
21 | add_executable(conntest conntest.cpp)
22 | add_executable(pollsrv pollsrv.cpp)
23 | add_executable(epollsrv epollsrv.cpp)
24 | add_executable(gethostbyname_test gethostbyname_test.cpp)
25 | add_executable(p2pcli p2pcli.cpp)
26 | add_executable(p2pserv p2pserv.cpp)
27 | add_executable(udpsrv udpsrv.cpp)
28 | add_executable(udpcli udpcli.cpp)
29 | add_executable(udpmulclt udpmulclt.cpp)
30 | add_executable(udpmulsrv udpmulsrv.cpp)
31 | add_executable(unixcli unixcli.cpp)
32 | add_executable(unixsrv unixsrv.cpp)
33 | add_executable(sockpair sockpair.cpp)
34 | add_executable(sockpair02 sockpair02.cpp)
35 | add_executable(msgget msgget.cpp)
36 | add_executable(msgctl01 msgctl01.cpp)
37 | add_executable(msgctl02 msgctl02.cpp)
38 | add_executable(msg_send msg_send.cpp)
39 | add_executable(msg_recv msg_recv.cpp)
40 | add_executable(msgcli msgcli.cpp)
41 | add_executable(msgsrv msgsrv.cpp)
42 | add_executable(mmap_recv mmap_recv.cpp)
43 | add_executable(mmap_send mmap_send.cpp)
44 | add_executable(shmread shmread.cpp)
45 | add_executable(shmwrite shmwrite.cpp)
46 | add_executable(sem sem.cpp)
47 | add_executable(sem02 sem02.cpp)
48 | add_executable(sem03 sem03.cpp)
49 | add_executable(01mqopen 01mqopen.cpp)
50 | add_executable(02myunlink 02myunlink.cpp)
51 | add_executable(03mqgetattr 03mqgetattr.cpp)
52 | add_executable(04mqsend 04mqsend.cpp)
53 | add_executable(05mqreceive 05mqreceive.cpp)
54 | add_executable(06mqnotify 06mqnotify.cpp)
55 | add_executable(01shmopen 01shmopen.cpp)
56 | add_executable(02shmunlink 02shmunlink.cpp)
57 | add_executable(03shmwrite 03shmwrite.cpp)
58 | add_executable(04shmreceive 04shmreceive.cpp)
59 | add_executable(thread_create thread_create.cpp)
60 | add_executable(threadechosrv threadechosrv.cpp)
61 | add_executable(thread thread.cpp)
62 | add_executable(pctest pctest.cpp)
63 | add_executable(condtest condtest.cpp)
64 |
65 | add_subdirectory(udpchat)
66 | add_subdirectory(shmfifo)
67 | add_subdirectory(threadpool)
68 |
69 | set(semsrc
70 | sem.cpp)
71 |
72 | add_library(semtool ${semsrc})
73 |
74 | target_link_libraries(01mqopen rt)
75 | target_link_libraries(02myunlink rt)
76 | target_link_libraries(03mqgetattr rt)
77 | target_link_libraries(04mqsend rt)
78 | target_link_libraries(05mqreceive rt)
79 | target_link_libraries(06mqnotify rt)
80 | target_link_libraries(01shmopen rt)
81 | target_link_libraries(02shmunlink rt)
82 | target_link_libraries(03shmwrite rt)
83 | target_link_libraries(04shmreceive rt)
84 | target_link_libraries(thread_create pthread)
85 | target_link_libraries(threadechosrv pthread)
86 | target_link_libraries(thread pthread)
87 | target_link_libraries(pctest pthread rt)
88 | target_link_libraries(condtest pthread rt)
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # NetworkProgramming
2 | Linux网络编程视频教程
3 | 编译环境 Linux + CLion
4 |
5 | 视频地址 https://www.bilibili.com/video/av33813135/
6 | 从p13 socket编程8开始在文件开头标注该代码属于哪个视频
7 |
8 | 前面章节 echocli* echosrv* 依次按顺序匹配
9 |
10 | ## linux编译
11 | >> cmake .
12 | >> make
13 |
14 | 个人体会:之前没看这个,[muduo](https://github.com/834810071/muduo_study)基本上看不懂,看过之后,[muduo](https://github.com/834810071/muduo_study)基本上就没啥难度了。
15 |
--------------------------------------------------------------------------------
/condtest.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-15.
3 | //
4 |
5 | // p39 posix信号量与互斥锁
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include /* For O_* constants */
12 | #include /* For mode constants */
13 | #include
14 | #include
15 |
16 | using namespace std;
17 |
18 | #define ERR_EXIT(m) \
19 | do \
20 | { \
21 | perror(m); \
22 | exit(EXIT_FAILURE); \
23 | } while(0);
24 |
25 | #define CONSUMERS_COUNT 1
26 | #define PRODUCERS_COUNT 1
27 |
28 | pthread_mutex_t g_mutex;
29 | pthread_cond_t g_cond;
30 |
31 | pthread_t g_thread[CONSUMERS_COUNT + PRODUCERS_COUNT];
32 |
33 | int ready = 0;
34 |
35 | void *produce (void *arg)
36 | {
37 | int num = *((int *)arg);
38 | int i;
39 | while (1)
40 | {
41 | printf("%d produce is waiting\n", num);
42 | pthread_mutex_lock(&g_mutex);
43 | printf("%d produce begin produce product %d\n", num, ready);
44 |
45 | while (ready == 0)
46 | {
47 | pthread_cond_wait(&g_cond, &g_mutex);
48 | }
49 |
50 | printf("%d produce end produce product %d\n", num, ready++);
51 | pthread_mutex_unlock(&g_mutex);
52 | sleep(1);
53 | }
54 | return NULL;
55 | }
56 |
57 | void *consume (void *arg)
58 | {
59 | int num = *((int *)arg);
60 | int i;
61 | while (1)
62 | {
63 | printf("%d consume is waiting\n", num);
64 | pthread_mutex_lock(&g_mutex);
65 | printf("%d consume begin consume product %d\n", num, ready);
66 |
67 | ++ready;
68 | pthread_cond_signal(&g_cond);
69 |
70 | printf("%d consume end consume product %d\n", num, ready);
71 | pthread_mutex_unlock(&g_mutex);
72 | sleep(1);
73 | }
74 | return NULL;
75 | }
76 |
77 | int main(int argc, char** argv)
78 | {
79 |
80 | pthread_mutex_init(&g_mutex, NULL);
81 | pthread_cond_init(&g_cond, NULL);
82 |
83 | int i;
84 | for (i = 0; i < CONSUMERS_COUNT; ++i)
85 | {
86 | pthread_create(&g_thread[i], NULL, consume, &i);
87 | }
88 | sleep(1);
89 | for (i = 0; i < PRODUCERS_COUNT; ++i)
90 | {
91 | pthread_create(&g_thread[CONSUMERS_COUNT+i], NULL, produce, &i);
92 | }
93 |
94 | for (i = 0; i < CONSUMERS_COUNT + PRODUCERS_COUNT; ++i)
95 | {
96 | pthread_join(g_thread[i], NULL);
97 | }
98 |
99 | pthread_mutex_destroy(&g_mutex);
100 | pthread_cond_destroy(&g_cond);
101 |
102 | return 0;
103 | }
--------------------------------------------------------------------------------
/conntest.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-7.
3 | //
4 |
5 | // socket 编程 12
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 |
18 |
19 | using namespace std;
20 |
21 | struct packet
22 | {
23 | int len;
24 | char buf[1024];
25 | };
26 |
27 | #define ERR_EXIT(m) \
28 | do \
29 | { \
30 | perror(m); \
31 | exit(EXIT_FAILURE); \
32 | } while(0);
33 |
34 | ssize_t readn(int fd, void *buf, size_t count)
35 | {
36 | size_t nleft = count; // 剩余字节数
37 | ssize_t nread;
38 | char *bufp = (char*) buf;
39 |
40 | while (nleft > 0)
41 | {
42 | nread = read(fd, bufp, nleft);
43 | if (nread < 0)
44 | {
45 | if (errno == EINTR)
46 | {
47 | continue;
48 | }
49 | return -1;
50 | } else if (nread == 0)
51 | {
52 | return count - nleft;
53 | }
54 |
55 | bufp += nread;
56 | nleft -= nread;
57 | }
58 | return count;
59 | }
60 |
61 | ssize_t writen(int fd, const void *buf, size_t count)
62 | {
63 | size_t nleft = count;
64 | ssize_t nwritten;
65 | char* bufp = (char*)buf;
66 |
67 | while (nleft > 0)
68 | {
69 | if ((nwritten = write(fd, bufp, nleft)) < 0)
70 | {
71 | if (errno == EINTR)
72 | {
73 | continue;
74 | }
75 | return -1;
76 | }
77 | else if (nwritten == 0)
78 | {
79 | continue;
80 | }
81 | bufp += nwritten;
82 | nleft -= nwritten;
83 | }
84 | return count;
85 | }
86 |
87 |
88 | ssize_t recv_peek(int sockfd, void *buf, size_t len)
89 | {
90 | while (1)
91 | {
92 | int ret = recv(sockfd, buf, len, MSG_PEEK); // 查看传入消息
93 | if (ret == -1 && errno == EINTR)
94 | {
95 | continue;
96 | }
97 | return ret;
98 | }
99 | }
100 |
101 | ssize_t readline(int sockfd, void *buf, size_t maxline)
102 | {
103 | int ret;
104 | int nread;
105 | char *bufp = (char*)buf; // 当前指针位置
106 | int nleft = maxline;
107 | while (1)
108 | {
109 | ret = recv_peek(sockfd, buf, nleft);
110 | if (ret < 0)
111 | {
112 | return ret;
113 | }
114 | else if (ret == 0)
115 | {
116 | return ret;
117 | }
118 | nread = ret;
119 | int i;
120 | for (i = 0; i < nread; i++)
121 | {
122 | if (bufp[i] == '\n')
123 | {
124 | ret = readn(sockfd, bufp, i+1);
125 | if (ret != i+1)
126 | {
127 | exit(EXIT_FAILURE);
128 | }
129 | return ret;
130 | }
131 | }
132 | if (nread > nleft)
133 | {
134 | exit(EXIT_FAILURE);
135 | }
136 | nleft -= nread;
137 | ret = readn(sockfd, bufp, nread);
138 | if (ret != nread)
139 | {
140 | exit(EXIT_FAILURE);
141 | }
142 | bufp += nread;
143 | }
144 | return -1;
145 | }
146 |
147 | void ehco_cli(int sockfd)
148 | {
149 | // char recvbuf[1024];
150 | // char sendbuf[1024];
151 | // // struct packet recvbuf;
152 | // // struct packet sendbuf;
153 | // memset(recvbuf, 0, sizeof recvbuf);
154 | // memset(sendbuf, 0, sizeof sendbuf);
155 | // int n = 0;
156 | // while (fgets(sendbuf, sizeof sendbuf, stdin) != NULL) // 键盘输入获取
157 | // {
158 | // writen(sockfd, sendbuf, strlen(sendbuf)); // 写入服务器
159 | //
160 | // int ret = readline(sockfd, recvbuf, sizeof recvbuf); // 服务器读取
161 | // if (ret == -1)
162 | // {
163 | // ERR_EXIT("readline");
164 | // }
165 | // if (ret == 0)
166 | // {
167 | // printf("server close\n");
168 | // break;
169 | // }
170 | //
171 | // fputs(recvbuf, stdout); // 服务器返回数据输出
172 | //
173 | // // 清空
174 | // memset(recvbuf, 0, sizeof recvbuf);
175 | // memset(sendbuf, 0, sizeof sendbuf);
176 | // }
177 | fd_set rset;
178 | FD_ZERO(&rset);
179 |
180 | int nready;
181 | int maxfd;
182 | int fd_stdin = fileno(stdin);
183 | if (fd_stdin > sockfd)
184 | {
185 | maxfd = fd_stdin;
186 | } else {
187 | maxfd = sockfd;
188 | }
189 |
190 | char sendbuf[1024] = {0};
191 | char recvbuf[1024] = {0};
192 |
193 | while (1)
194 | {
195 | FD_SET(fd_stdin, &rset);
196 | FD_SET(sockfd, &rset);
197 | nready = select(maxfd+1, &rset, NULL, NULL, NULL);
198 | if (nready == -1)
199 | {
200 | ERR_EXIT("select");
201 | }
202 | if (nready == 0)
203 | {
204 | continue;
205 | }
206 |
207 | if (FD_ISSET(sockfd, &rset)) // sock数据 读取
208 | {
209 | int ret = readline(sockfd, recvbuf, sizeof recvbuf); // 服务器读取
210 | if (ret == -1)
211 | {
212 | ERR_EXIT("readline");
213 | }
214 | if (ret == 0)
215 | {
216 | printf("server close\n");
217 | break;
218 | }
219 |
220 | fputs(recvbuf, stdout); // 服务器返回数据输出
221 | memset(recvbuf, 0, sizeof(recvbuf));
222 | }
223 |
224 | if (FD_ISSET(fd_stdin, &rset))
225 | {
226 | if (fgets(sendbuf, sizeof sendbuf, stdin) == NULL) // 键盘输入获取
227 | {
228 | // shutdown(sockfd, SHUT_WR);
229 | //close(sockfd);
230 | break;
231 | } else {
232 | writen(sockfd, sendbuf, strlen(sendbuf)); // 写入服务器
233 | }
234 | }
235 | }
236 | close(sockfd);
237 | };
238 |
239 | void handle_sigchld(int sig)
240 | {
241 | // wait(NULL);
242 | while (waitpid(-1, NULL, WNOHANG) > 0);
243 | }
244 |
245 | int main(int argc, char** argv) {
246 | int count = 0;
247 | while (1) {
248 | // signal(SIGCHLD, SIG_IGN);
249 | signal(SIGCHLD, handle_sigchld);
250 | // 1. 创建套接字
251 | int sockfd;
252 | if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
253 | ERR_EXIT("socket");
254 | }
255 |
256 | // 2. 分配套接字地址
257 | struct sockaddr_in servaddr;
258 | memset(&servaddr, 0, sizeof servaddr);
259 | servaddr.sin_family = AF_INET;
260 | servaddr.sin_port = htons(6666);
261 | // servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
262 | servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
263 | // inet_aton("127.0.0.1", &servaddr.sin_addr);
264 |
265 | // 3. 请求链接
266 | if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof servaddr) < 0) {
267 | ERR_EXIT("connect");
268 | }
269 |
270 | struct sockaddr_in localaddr;
271 | socklen_t addrlen = sizeof localaddr;
272 | if (getsockname(sockfd, (struct sockaddr *) &localaddr, &addrlen) < 0) {
273 | ERR_EXIT("getsockname");
274 | }
275 | printf("id = %s, ", inet_ntoa(localaddr.sin_addr));
276 | printf("port = %d\n", ntohs(localaddr.sin_port));
277 | printf("count = %d\n", ++count);
278 | // 4. 数据交换
279 | //ehco_cli(sockfd);
280 |
281 | // 5. 断开连接
282 | //close(sockfd);
283 | }
284 |
285 | return 0;
286 | }
287 |
--------------------------------------------------------------------------------
/echocli.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-7-17.
3 | //
4 |
5 | // 视频 1
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 |
17 | using namespace std;
18 |
19 | #define ERR_EXIT(m) \
20 | do \
21 | { \
22 | perror(m); \
23 | exit(EXIT_FAILURE); \
24 | } while(0);
25 |
26 | int main(int argc, char** argv) {
27 | // 1. 创建套接字
28 | int sockfd;
29 | if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
30 | ERR_EXIT("socket");
31 | }
32 |
33 | // 2. 分配套接字地址
34 | struct sockaddr_in servaddr;
35 | memset(&servaddr, 0, sizeof servaddr);
36 | servaddr.sin_family = AF_INET;
37 | servaddr.sin_port = htons(6666);
38 | // servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
39 | servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
40 | // inet_aton("127.0.0.1", &servaddr.sin_addr);
41 |
42 | // 3. 请求链接
43 | if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof servaddr) < 0) {
44 | ERR_EXIT("connect");
45 | }
46 |
47 | // 4. 数据交换
48 | char recvbuf[1024];
49 | char sendbuf[1024];
50 | while (fgets(sendbuf, sizeof sendbuf, stdin) != NULL) // 键盘输入获取
51 | {
52 | // memset(recvbuf, 0, sizeof recvbuf);
53 | // memset(sendbuf, 0, sizeof sendbuf);
54 | write(sockfd, sendbuf, sizeof sendbuf); // 写入服务器
55 | int ret = read(sockfd, recvbuf, sizeof recvbuf); // 服务器读取
56 | if (ret == 0)
57 | {
58 |
59 | } else
60 | {
61 |
62 | }
63 | fputs(recvbuf, stdout); // 服务器返回数据输出
64 |
65 | // 清空
66 | memset(recvbuf, 0, sizeof recvbuf);
67 | memset(sendbuf, 0, sizeof sendbuf);
68 | }
69 |
70 | // 5. 断开连接
71 | close(sockfd);
72 |
73 |
74 |
75 | return 0;
76 | }
77 |
--------------------------------------------------------------------------------
/echocli2.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-7-17.
3 | //
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 |
15 | using namespace std;
16 |
17 | #define ERR_EXIT(m) \
18 | do \
19 | { \
20 | perror(m); \
21 | exit(EXIT_FAILURE); \
22 | } while(0);
23 |
24 | int main(int argc, char** argv) {
25 | // 1. 创建套接字
26 | int sockfd;
27 | if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
28 | ERR_EXIT("socket");
29 | }
30 |
31 | // 2. 分配套接字地址
32 | struct sockaddr_in servaddr;
33 | memset(&servaddr, 0, sizeof servaddr);
34 | servaddr.sin_family = AF_INET;
35 | servaddr.sin_port = htons(6666);
36 | // servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
37 | servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
38 | // inet_aton("127.0.0.1", &servaddr.sin_addr);
39 |
40 | // 3. 请求链接
41 | if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof servaddr) < 0) {
42 | ERR_EXIT("connect");
43 | }
44 |
45 | // 4. 数据交换
46 | char recvbuf[1024];
47 | char sendbuf[1024];
48 | while (fgets(sendbuf, sizeof sendbuf, stdin) != NULL) // 键盘输入获取
49 | {
50 | // memset(recvbuf, 0, sizeof recvbuf);
51 | // memset(sendbuf, 0, sizeof sendbuf);
52 | write(sockfd, sendbuf, sizeof sendbuf); // 写入服务器
53 | int ret = read(sockfd, recvbuf, sizeof recvbuf); // 服务器读取
54 | if (ret == 0)
55 | {
56 | printf("server close\n");
57 | break;
58 | } else if (ret == -1)
59 | {
60 | ERR_EXIT("read");
61 | }
62 | fputs(recvbuf, stdout); // 服务器返回数据输出
63 |
64 | // 清空
65 | memset(recvbuf, 0, sizeof recvbuf);
66 | memset(sendbuf, 0, sizeof sendbuf);
67 | }
68 |
69 | // 5. 断开连接
70 | close(sockfd);
71 |
72 |
73 |
74 | return 0;
75 | }
--------------------------------------------------------------------------------
/echocli3.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-7-21.
3 | //
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 |
15 | using namespace std;
16 |
17 | struct packet
18 | {
19 | int len;
20 | char buf[1024];
21 | };
22 |
23 | #define ERR_EXIT(m) \
24 | do \
25 | { \
26 | perror(m); \
27 | exit(EXIT_FAILURE); \
28 | } while(0);
29 |
30 | ssize_t readn(int fd, void *buf, size_t count)
31 | {
32 | size_t nleft = count; // 剩余字节数
33 | ssize_t nread;
34 | char *bufp = (char*) buf;
35 |
36 | while (nleft > 0)
37 | {
38 | nread = read(fd, bufp, nleft);
39 | if (nread < 0)
40 | {
41 | if (errno == EINTR)
42 | {
43 | continue;
44 | }
45 | return -1;
46 | } else if (nread == 0)
47 | {
48 | return count - nleft;
49 | }
50 |
51 | bufp += nread;
52 | nleft -= nread;
53 | }
54 | return count;
55 | }
56 |
57 | ssize_t writen(int fd, const void *buf, size_t count)
58 | {
59 | size_t nleft = count;
60 | ssize_t nwritten;
61 | char* bufp = (char*)buf;
62 |
63 | while (nleft > 0)
64 | {
65 | if ((nwritten = write(fd, bufp, nleft)) < 0)
66 | {
67 | if (errno == EINTR)
68 | {
69 | continue;
70 | }
71 | return -1;
72 | }
73 | else if (nwritten == 0)
74 | {
75 | continue;
76 | }
77 | bufp += nwritten;
78 | nleft -= nwritten;
79 | }
80 | return count;
81 | }
82 |
83 | int main(int argc, char** argv) {
84 | // 1. 创建套接字
85 | int sockfd;
86 | if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
87 | ERR_EXIT("socket");
88 | }
89 |
90 | // 2. 分配套接字地址
91 | struct sockaddr_in servaddr;
92 | memset(&servaddr, 0, sizeof servaddr);
93 | servaddr.sin_family = AF_INET;
94 | servaddr.sin_port = htons(6666);
95 | // servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
96 | servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
97 | // inet_aton("127.0.0.1", &servaddr.sin_addr);
98 |
99 | // 3. 请求链接
100 | if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof servaddr) < 0) {
101 | ERR_EXIT("connect");
102 | }
103 |
104 | // 4. 数据交换
105 | // char recvbuf[1024];
106 | // char sendbuf[1024];
107 | struct packet recvbuf;
108 | struct packet sendbuf;
109 | memset(&recvbuf, 0, sizeof recvbuf);
110 | memset(&sendbuf, 0, sizeof sendbuf);
111 | int n = 0;
112 | while (fgets(sendbuf.buf, sizeof sendbuf.buf, stdin) != NULL) // 键盘输入获取
113 | {
114 | n = strlen(sendbuf.buf);
115 | sendbuf.len = htonl(n); // 主机字节序转换为网络字节序
116 | writen(sockfd, &sendbuf, 4+n); // 写入服务器
117 |
118 | int ret = readn(sockfd, &recvbuf.len, 4); // 服务器读取
119 | if (ret == -1)
120 | {
121 | ERR_EXIT("read");
122 | }
123 | else if (ret < 4)
124 | {
125 | printf("server close\n");
126 | break;
127 | }
128 |
129 | n = ntohl(recvbuf.len);
130 | ret = readn(sockfd, &recvbuf.buf, n);
131 | if (ret == -1)
132 | {
133 | ERR_EXIT("read");
134 | }
135 | else if (ret < n)
136 | {
137 | printf("server close\n");
138 | break;
139 | }
140 |
141 | fputs(recvbuf.buf, stdout); // 服务器返回数据输出
142 |
143 | // 清空
144 | memset(&recvbuf, 0, sizeof recvbuf);
145 | memset(&sendbuf, 0, sizeof sendbuf);
146 | }
147 |
148 | // 5. 断开连接
149 | close(sockfd);
150 |
151 |
152 | return 0;
153 | }
--------------------------------------------------------------------------------
/echocli4.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-6.
3 | //
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 |
15 | using namespace std;
16 |
17 | struct packet
18 | {
19 | int len;
20 | char buf[1024];
21 | };
22 |
23 | #define ERR_EXIT(m) \
24 | do \
25 | { \
26 | perror(m); \
27 | exit(EXIT_FAILURE); \
28 | } while(0);
29 |
30 | ssize_t readn(int fd, void *buf, size_t count)
31 | {
32 | size_t nleft = count; // 剩余字节数
33 | ssize_t nread;
34 | char *bufp = (char*) buf;
35 |
36 | while (nleft > 0)
37 | {
38 | nread = read(fd, bufp, nleft);
39 | if (nread < 0)
40 | {
41 | if (errno == EINTR)
42 | {
43 | continue;
44 | }
45 | return -1;
46 | } else if (nread == 0)
47 | {
48 | return count - nleft;
49 | }
50 |
51 | bufp += nread;
52 | nleft -= nread;
53 | }
54 | return count;
55 | }
56 |
57 | ssize_t writen(int fd, const void *buf, size_t count)
58 | {
59 | size_t nleft = count;
60 | ssize_t nwritten;
61 | char* bufp = (char*)buf;
62 |
63 | while (nleft > 0)
64 | {
65 | if ((nwritten = write(fd, bufp, nleft)) < 0)
66 | {
67 | if (errno == EINTR)
68 | {
69 | continue;
70 | }
71 | return -1;
72 | }
73 | else if (nwritten == 0)
74 | {
75 | continue;
76 | }
77 | bufp += nwritten;
78 | nleft -= nwritten;
79 | }
80 | return count;
81 | }
82 |
83 |
84 | ssize_t recv_peek(int sockfd, void *buf, size_t len)
85 | {
86 | while (1)
87 | {
88 | int ret = recv(sockfd, buf, len, MSG_PEEK); // 查看传入消息
89 | if (ret == -1 && errno == EINTR)
90 | {
91 | continue;
92 | }
93 | return ret;
94 | }
95 | }
96 |
97 | ssize_t readline(int sockfd, void *buf, size_t maxline)
98 | {
99 | int ret;
100 | int nread;
101 | char *bufp = (char*)buf; // 当前指针位置
102 | int nleft = maxline;
103 | while (1)
104 | {
105 | ret = recv_peek(sockfd, buf, nleft);
106 | if (ret < 0)
107 | {
108 | return ret;
109 | }
110 | else if (ret == 0)
111 | {
112 | return ret;
113 | }
114 | nread = ret;
115 | int i;
116 | for (i = 0; i < nread; i++)
117 | {
118 | if (bufp[i] == '\n')
119 | {
120 | ret = readn(sockfd, bufp, i+1);
121 | if (ret != i+1)
122 | {
123 | exit(EXIT_FAILURE);
124 | }
125 | return ret;
126 | }
127 | }
128 | if (nread > nleft)
129 | {
130 | exit(EXIT_FAILURE);
131 | }
132 | nleft -= nread;
133 | ret = readn(sockfd, bufp, nread);
134 | if (ret != nread)
135 | {
136 | exit(EXIT_FAILURE);
137 | }
138 | bufp += nread;
139 | }
140 | return -1;
141 | }
142 |
143 | int main(int argc, char** argv) {
144 | // 1. 创建套接字
145 | int sockfd;
146 | if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
147 | ERR_EXIT("socket");
148 | }
149 |
150 | // 2. 分配套接字地址
151 | struct sockaddr_in servaddr;
152 | memset(&servaddr, 0, sizeof servaddr);
153 | servaddr.sin_family = AF_INET;
154 | servaddr.sin_port = htons(6666);
155 | // servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
156 | servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
157 | // inet_aton("127.0.0.1", &servaddr.sin_addr);
158 |
159 | // 3. 请求链接
160 | if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof servaddr) < 0) {
161 | ERR_EXIT("connect");
162 | }
163 |
164 | struct sockaddr_in localaddr;
165 | socklen_t addrlen = sizeof localaddr;
166 | if (getsockname(sockfd, (struct sockaddr*)&localaddr, &addrlen) < 0)
167 | {
168 | ERR_EXIT("getsockname");
169 | }
170 | printf("id = %s, ", inet_ntoa(localaddr.sin_addr));
171 | printf("port = %d\n", ntohs(localaddr.sin_port));
172 |
173 | // 4. 数据交换
174 | char recvbuf[1024];
175 | char sendbuf[1024];
176 | // struct packet recvbuf;
177 | // struct packet sendbuf;
178 | memset(recvbuf, 0, sizeof recvbuf);
179 | memset(sendbuf, 0, sizeof sendbuf);
180 | int n = 0;
181 | while (fgets(sendbuf, sizeof sendbuf, stdin) != NULL) // 键盘输入获取
182 | {
183 | writen(sockfd, sendbuf, strlen(sendbuf)); // 写入服务器
184 |
185 | int ret = readline(sockfd, recvbuf, sizeof recvbuf); // 服务器读取
186 | if (ret == -1)
187 | {
188 | ERR_EXIT("readline");
189 | }
190 | if (ret == 0)
191 | {
192 | printf("server close\n");
193 | break;
194 | }
195 |
196 | fputs(recvbuf, stdout); // 服务器返回数据输出
197 |
198 | // 清空
199 | memset(recvbuf, 0, sizeof recvbuf);
200 | memset(sendbuf, 0, sizeof sendbuf);
201 | }
202 |
203 | // 5. 断开连接
204 | close(sockfd);
205 |
206 |
207 | return 0;
208 | }
--------------------------------------------------------------------------------
/echocli5.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-6.
3 | //
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 |
17 | using namespace std;
18 |
19 | struct packet
20 | {
21 | int len;
22 | char buf[1024];
23 | };
24 |
25 | #define ERR_EXIT(m) \
26 | do \
27 | { \
28 | perror(m); \
29 | exit(EXIT_FAILURE); \
30 | } while(0);
31 |
32 | ssize_t readn(int fd, void *buf, size_t count)
33 | {
34 | size_t nleft = count; // 剩余字节数
35 | ssize_t nread;
36 | char *bufp = (char*) buf;
37 |
38 | while (nleft > 0)
39 | {
40 | nread = read(fd, bufp, nleft);
41 | if (nread < 0)
42 | {
43 | if (errno == EINTR)
44 | {
45 | continue;
46 | }
47 | return -1;
48 | } else if (nread == 0)
49 | {
50 | return count - nleft;
51 | }
52 |
53 | bufp += nread;
54 | nleft -= nread;
55 | }
56 | return count;
57 | }
58 |
59 | ssize_t writen(int fd, const void *buf, size_t count)
60 | {
61 | size_t nleft = count;
62 | ssize_t nwritten;
63 | char* bufp = (char*)buf;
64 |
65 | while (nleft > 0)
66 | {
67 | if ((nwritten = write(fd, bufp, nleft)) < 0)
68 | {
69 | if (errno == EINTR)
70 | {
71 | continue;
72 | }
73 | return -1;
74 | }
75 | else if (nwritten == 0)
76 | {
77 | continue;
78 | }
79 | bufp += nwritten;
80 | nleft -= nwritten;
81 | }
82 | return count;
83 | }
84 |
85 |
86 | ssize_t recv_peek(int sockfd, void *buf, size_t len)
87 | {
88 | while (1)
89 | {
90 | int ret = recv(sockfd, buf, len, MSG_PEEK); // 查看传入消息
91 | if (ret == -1 && errno == EINTR)
92 | {
93 | continue;
94 | }
95 | return ret;
96 | }
97 | }
98 |
99 | ssize_t readline(int sockfd, void *buf, size_t maxline)
100 | {
101 | int ret;
102 | int nread;
103 | char *bufp = (char*)buf; // 当前指针位置
104 | int nleft = maxline;
105 | while (1)
106 | {
107 | ret = recv_peek(sockfd, buf, nleft);
108 | if (ret < 0)
109 | {
110 | return ret;
111 | }
112 | else if (ret == 0)
113 | {
114 | return ret;
115 | }
116 | nread = ret;
117 | int i;
118 | for (i = 0; i < nread; i++)
119 | {
120 | if (bufp[i] == '\n')
121 | {
122 | ret = readn(sockfd, bufp, i+1);
123 | if (ret != i+1)
124 | {
125 | exit(EXIT_FAILURE);
126 | }
127 | return ret;
128 | }
129 | }
130 | if (nread > nleft)
131 | {
132 | exit(EXIT_FAILURE);
133 | }
134 | nleft -= nread;
135 | ret = readn(sockfd, bufp, nread);
136 | if (ret != nread)
137 | {
138 | exit(EXIT_FAILURE);
139 | }
140 | bufp += nread;
141 | }
142 | return -1;
143 | }
144 |
145 | void ehco_cli(int sockfd)
146 | {
147 | char recvbuf[1024];
148 | char sendbuf[1024];
149 | // struct packet recvbuf;
150 | // struct packet sendbuf;
151 | memset(recvbuf, 0, sizeof recvbuf);
152 | memset(sendbuf, 0, sizeof sendbuf);
153 | int n = 0;
154 | while (fgets(sendbuf, sizeof sendbuf, stdin) != NULL) // 键盘输入获取
155 | {
156 | writen(sockfd, sendbuf, strlen(sendbuf)); // 写入服务器
157 |
158 | int ret = readline(sockfd, recvbuf, sizeof recvbuf); // 服务器读取
159 | if (ret == -1)
160 | {
161 | ERR_EXIT("readline");
162 | }
163 | if (ret == 0)
164 | {
165 | printf("server close\n");
166 | break;
167 | }
168 |
169 | fputs(recvbuf, stdout); // 服务器返回数据输出
170 |
171 | // 清空
172 | memset(recvbuf, 0, sizeof recvbuf);
173 | memset(sendbuf, 0, sizeof sendbuf);
174 | }
175 | }
176 |
177 | void handle_sigchld(int sig)
178 | {
179 | // wait(NULL);
180 | while (waitpid(-1, NULL, WNOHANG) > 0);
181 | }
182 |
183 | int main(int argc, char** argv) {
184 | // signal(SIGCHLD, SIG_IGN);
185 | signal(SIGCHLD, handle_sigchld);
186 | // 1. 创建套接字
187 | int sockfd[5];
188 | int i;
189 | for (i = 0; i < 5; ++i)
190 | {
191 | if ((sockfd[i] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
192 | ERR_EXIT("socket");
193 | }
194 |
195 | // 2. 分配套接字地址
196 | struct sockaddr_in servaddr;
197 | memset(&servaddr, 0, sizeof servaddr);
198 | servaddr.sin_family = AF_INET;
199 | servaddr.sin_port = htons(6666);
200 | // servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
201 | servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
202 | // inet_aton("127.0.0.1", &servaddr.sin_addr);
203 |
204 | // 3. 请求链接
205 | if (connect(sockfd[i], (struct sockaddr *) &servaddr, sizeof servaddr) < 0) {
206 | ERR_EXIT("connect");
207 | }
208 |
209 | struct sockaddr_in localaddr;
210 | socklen_t addrlen = sizeof localaddr;
211 | if (getsockname(sockfd[i], (struct sockaddr*)&localaddr, &addrlen) < 0)
212 | {
213 | ERR_EXIT("getsockname");
214 | }
215 | printf("id = %s, ", inet_ntoa(localaddr.sin_addr));
216 | printf("port = %d\n", ntohs(localaddr.sin_port));
217 |
218 | }
219 | // 4. 数据交换
220 | ehco_cli(sockfd[0]);
221 |
222 | // 5. 断开连接
223 | close(sockfd[0]);
224 |
225 |
226 | return 0;
227 | }
--------------------------------------------------------------------------------
/echocli6.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-6.
3 | //
4 |
5 | // socket编程 8 select模型
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 |
18 |
19 | using namespace std;
20 |
21 | struct packet
22 | {
23 | int len;
24 | char buf[1024];
25 | };
26 |
27 | #define ERR_EXIT(m) \
28 | do \
29 | { \
30 | perror(m); \
31 | exit(EXIT_FAILURE); \
32 | } while(0);
33 |
34 | ssize_t readn(int fd, void *buf, size_t count)
35 | {
36 | size_t nleft = count; // 剩余字节数
37 | ssize_t nread;
38 | char *bufp = (char*) buf;
39 |
40 | while (nleft > 0)
41 | {
42 | nread = read(fd, bufp, nleft);
43 | if (nread < 0)
44 | {
45 | if (errno == EINTR)
46 | {
47 | continue;
48 | }
49 | return -1;
50 | } else if (nread == 0)
51 | {
52 | return count - nleft;
53 | }
54 |
55 | bufp += nread;
56 | nleft -= nread;
57 | }
58 | return count;
59 | }
60 |
61 | ssize_t writen(int fd, const void *buf, size_t count)
62 | {
63 | size_t nleft = count;
64 | ssize_t nwritten;
65 | char* bufp = (char*)buf;
66 |
67 | while (nleft > 0)
68 | {
69 | if ((nwritten = write(fd, bufp, nleft)) < 0)
70 | {
71 | if (errno == EINTR)
72 | {
73 | continue;
74 | }
75 | return -1;
76 | }
77 | else if (nwritten == 0)
78 | {
79 | continue;
80 | }
81 | bufp += nwritten;
82 | nleft -= nwritten;
83 | }
84 | return count;
85 | }
86 |
87 |
88 | ssize_t recv_peek(int sockfd, void *buf, size_t len)
89 | {
90 | while (1)
91 | {
92 | int ret = recv(sockfd, buf, len, MSG_PEEK); // 查看传入消息
93 | if (ret == -1 && errno == EINTR)
94 | {
95 | continue;
96 | }
97 | return ret;
98 | }
99 | }
100 |
101 | ssize_t readline(int sockfd, void *buf, size_t maxline)
102 | {
103 | int ret;
104 | int nread;
105 | char *bufp = (char*)buf; // 当前指针位置
106 | int nleft = maxline;
107 | while (1)
108 | {
109 | ret = recv_peek(sockfd, buf, nleft);
110 | if (ret < 0)
111 | {
112 | return ret;
113 | }
114 | else if (ret == 0)
115 | {
116 | return ret;
117 | }
118 | nread = ret;
119 | int i;
120 | for (i = 0; i < nread; i++)
121 | {
122 | if (bufp[i] == '\n')
123 | {
124 | ret = readn(sockfd, bufp, i+1);
125 | if (ret != i+1)
126 | {
127 | exit(EXIT_FAILURE);
128 | }
129 | return ret;
130 | }
131 | }
132 | if (nread > nleft)
133 | {
134 | exit(EXIT_FAILURE);
135 | }
136 | nleft -= nread;
137 | ret = readn(sockfd, bufp, nread);
138 | if (ret != nread)
139 | {
140 | exit(EXIT_FAILURE);
141 | }
142 | bufp += nread;
143 | }
144 | return -1;
145 | }
146 |
147 | void ehco_cli(int sockfd)
148 | {
149 | // char recvbuf[1024];
150 | // char sendbuf[1024];
151 | // // struct packet recvbuf;
152 | // // struct packet sendbuf;
153 | // memset(recvbuf, 0, sizeof recvbuf);
154 | // memset(sendbuf, 0, sizeof sendbuf);
155 | // int n = 0;
156 | // while (fgets(sendbuf, sizeof sendbuf, stdin) != NULL) // 键盘输入获取
157 | // {
158 | // writen(sockfd, sendbuf, strlen(sendbuf)); // 写入服务器
159 | //
160 | // int ret = readline(sockfd, recvbuf, sizeof recvbuf); // 服务器读取
161 | // if (ret == -1)
162 | // {
163 | // ERR_EXIT("readline");
164 | // }
165 | // if (ret == 0)
166 | // {
167 | // printf("server close\n");
168 | // break;
169 | // }
170 | //
171 | // fputs(recvbuf, stdout); // 服务器返回数据输出
172 | //
173 | // // 清空
174 | // memset(recvbuf, 0, sizeof recvbuf);
175 | // memset(sendbuf, 0, sizeof sendbuf);
176 | // }
177 | fd_set rset;
178 | FD_ZERO(&rset);
179 |
180 | int nready;
181 | int maxfd;
182 | int fd_stdin = fileno(stdin);
183 | if (fd_stdin > sockfd)
184 | {
185 | maxfd = fd_stdin;
186 | } else {
187 | maxfd = sockfd;
188 | }
189 |
190 | char sendbuf[1024] = {0};
191 | char recvbuf[1024] = {0};
192 |
193 | while (1)
194 | {
195 | FD_SET(fd_stdin, &rset);
196 | FD_SET(sockfd, &rset);
197 | nready = select(maxfd+1, &rset, NULL, NULL, NULL);
198 | if (nready == -1)
199 | {
200 | ERR_EXIT("select");
201 | }
202 | if (nready == 0)
203 | {
204 | continue;
205 | }
206 |
207 | if (FD_ISSET(sockfd, &rset)) // sock数据 读取
208 | {
209 | int ret = readline(sockfd, recvbuf, sizeof recvbuf); // 服务器读取
210 | if (ret == -1)
211 | {
212 | ERR_EXIT("readline");
213 | }
214 | if (ret == 0)
215 | {
216 | printf("server close\n");
217 | break;
218 | }
219 |
220 | fputs(recvbuf, stdout); // 服务器返回数据输出
221 | memset(recvbuf, 0, sizeof(recvbuf));
222 | }
223 |
224 | if (FD_ISSET(fd_stdin, &rset))
225 | {
226 | if (fgets(sendbuf, sizeof sendbuf, stdin) == NULL) // 键盘输入获取
227 | {
228 | break;
229 | }
230 | writen(sockfd, sendbuf, strlen(sendbuf)); // 写入服务器
231 | }
232 | }
233 | close(sockfd);
234 | };
235 |
236 | void handle_sigchld(int sig)
237 | {
238 | // wait(NULL);
239 | while (waitpid(-1, NULL, WNOHANG) > 0);
240 | }
241 |
242 | int main(int argc, char** argv) {
243 | // signal(SIGCHLD, SIG_IGN);
244 | signal(SIGCHLD, handle_sigchld);
245 | // 1. 创建套接字
246 | int sockfd;
247 | if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
248 | ERR_EXIT("socket");
249 | }
250 |
251 | // 2. 分配套接字地址
252 | struct sockaddr_in servaddr;
253 | memset(&servaddr, 0, sizeof servaddr);
254 | servaddr.sin_family = AF_INET;
255 | servaddr.sin_port = htons(6666);
256 | // servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
257 | servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
258 | // inet_aton("127.0.0.1", &servaddr.sin_addr);
259 |
260 | // 3. 请求链接
261 | if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof servaddr) < 0) {
262 | ERR_EXIT("connect");
263 | }
264 |
265 | struct sockaddr_in localaddr;
266 | socklen_t addrlen = sizeof localaddr;
267 | if (getsockname(sockfd, (struct sockaddr*)&localaddr, &addrlen) < 0)
268 | {
269 | ERR_EXIT("getsockname");
270 | }
271 | printf("id = %s, ", inet_ntoa(localaddr.sin_addr));
272 | printf("port = %d\n", ntohs(localaddr.sin_port));
273 |
274 | // 4. 数据交换
275 | ehco_cli(sockfd);
276 |
277 | // 5. 断开连接
278 | close(sockfd);
279 |
280 |
281 | return 0;
282 | }
--------------------------------------------------------------------------------
/echocli7.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-7.
3 | //
4 |
5 | // socket编程 9
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 |
18 |
19 | using namespace std;
20 |
21 | struct packet
22 | {
23 | int len;
24 | char buf[1024];
25 | };
26 |
27 | #define ERR_EXIT(m) \
28 | do \
29 | { \
30 | perror(m); \
31 | exit(EXIT_FAILURE); \
32 | } while(0);
33 |
34 | ssize_t readn(int fd, void *buf, size_t count)
35 | {
36 | size_t nleft = count; // 剩余字节数
37 | ssize_t nread;
38 | char *bufp = (char*) buf;
39 |
40 | while (nleft > 0)
41 | {
42 | nread = read(fd, bufp, nleft);
43 | if (nread < 0)
44 | {
45 | if (errno == EINTR)
46 | {
47 | continue;
48 | }
49 | return -1;
50 | } else if (nread == 0)
51 | {
52 | return count - nleft;
53 | }
54 |
55 | bufp += nread;
56 | nleft -= nread;
57 | }
58 | return count;
59 | }
60 |
61 | ssize_t writen(int fd, const void *buf, size_t count)
62 | {
63 | size_t nleft = count;
64 | ssize_t nwritten;
65 | char* bufp = (char*)buf;
66 |
67 | while (nleft > 0)
68 | {
69 | if ((nwritten = write(fd, bufp, nleft)) < 0)
70 | {
71 | if (errno == EINTR)
72 | {
73 | continue;
74 | }
75 | return -1;
76 | }
77 | else if (nwritten == 0)
78 | {
79 | continue;
80 | }
81 | bufp += nwritten;
82 | nleft -= nwritten;
83 | }
84 | return count;
85 | }
86 |
87 |
88 | ssize_t recv_peek(int sockfd, void *buf, size_t len)
89 | {
90 | while (1)
91 | {
92 | int ret = recv(sockfd, buf, len, MSG_PEEK); // 查看传入消息
93 | if (ret == -1 && errno == EINTR)
94 | {
95 | continue;
96 | }
97 | return ret;
98 | }
99 | }
100 |
101 | ssize_t readline(int sockfd, void *buf, size_t maxline)
102 | {
103 | int ret;
104 | int nread;
105 | char *bufp = (char*)buf; // 当前指针位置
106 | int nleft = maxline;
107 | while (1)
108 | {
109 | ret = recv_peek(sockfd, buf, nleft);
110 | if (ret < 0)
111 | {
112 | return ret;
113 | }
114 | else if (ret == 0)
115 | {
116 | return ret;
117 | }
118 | nread = ret;
119 | int i;
120 | for (i = 0; i < nread; i++)
121 | {
122 | if (bufp[i] == '\n')
123 | {
124 | ret = readn(sockfd, bufp, i+1);
125 | if (ret != i+1)
126 | {
127 | exit(EXIT_FAILURE);
128 | }
129 | return ret;
130 | }
131 | }
132 | if (nread > nleft)
133 | {
134 | exit(EXIT_FAILURE);
135 | }
136 | nleft -= nread;
137 | ret = readn(sockfd, bufp, nread);
138 | if (ret != nread)
139 | {
140 | exit(EXIT_FAILURE);
141 | }
142 | bufp += nread;
143 | }
144 | return -1;
145 | }
146 |
147 | void ehco_cli(int sockfd)
148 | {
149 | // char recvbuf[1024];
150 | // char sendbuf[1024];
151 | // // struct packet recvbuf;
152 | // // struct packet sendbuf;
153 | // memset(recvbuf, 0, sizeof recvbuf);
154 | // memset(sendbuf, 0, sizeof sendbuf);
155 | // int n = 0;
156 | // while (fgets(sendbuf, sizeof sendbuf, stdin) != NULL) // 键盘输入获取
157 | // {
158 | // writen(sockfd, sendbuf, strlen(sendbuf)); // 写入服务器
159 | //
160 | // int ret = readline(sockfd, recvbuf, sizeof recvbuf); // 服务器读取
161 | // if (ret == -1)
162 | // {
163 | // ERR_EXIT("readline");
164 | // }
165 | // if (ret == 0)
166 | // {
167 | // printf("server close\n");
168 | // break;
169 | // }
170 | //
171 | // fputs(recvbuf, stdout); // 服务器返回数据输出
172 | //
173 | // // 清空
174 | // memset(recvbuf, 0, sizeof recvbuf);
175 | // memset(sendbuf, 0, sizeof sendbuf);
176 | // }
177 | fd_set rset;
178 | FD_ZERO(&rset);
179 |
180 | int nready;
181 | int maxfd;
182 | int fd_stdin = fileno(stdin);
183 | if (fd_stdin > sockfd)
184 | {
185 | maxfd = fd_stdin;
186 | } else {
187 | maxfd = sockfd;
188 | }
189 |
190 | char sendbuf[1024] = {0};
191 | char recvbuf[1024] = {0};
192 |
193 | while (1)
194 | {
195 | FD_SET(fd_stdin, &rset);
196 | FD_SET(sockfd, &rset);
197 | nready = select(maxfd+1, &rset, NULL, NULL, NULL);
198 | if (nready == -1)
199 | {
200 | ERR_EXIT("select");
201 | }
202 | if (nready == 0)
203 | {
204 | continue;
205 | }
206 |
207 | if (FD_ISSET(sockfd, &rset)) // sock数据 读取
208 | {
209 | int ret = readline(sockfd, recvbuf, sizeof recvbuf); // 服务器读取
210 | if (ret == -1)
211 | {
212 | ERR_EXIT("readline");
213 | }
214 | if (ret == 0)
215 | {
216 | printf("server close\n");
217 | break;
218 | }
219 |
220 | fputs(recvbuf, stdout); // 服务器返回数据输出
221 | memset(recvbuf, 0, sizeof(recvbuf));
222 | }
223 |
224 | if (FD_ISSET(fd_stdin, &rset))
225 | {
226 | if (fgets(sendbuf, sizeof sendbuf, stdin) == NULL) // 键盘输入获取
227 | {
228 | // shutdown(sockfd, SHUT_WR);
229 | //close(sockfd);
230 | break;
231 | } else {
232 | writen(sockfd, sendbuf, strlen(sendbuf)); // 写入服务器
233 | }
234 | }
235 | }
236 | close(sockfd);
237 | };
238 |
239 | void handle_sigchld(int sig)
240 | {
241 | // wait(NULL);
242 | while (waitpid(-1, NULL, WNOHANG) > 0);
243 | }
244 |
245 | int main(int argc, char** argv) {
246 | // signal(SIGCHLD, SIG_IGN);
247 | signal(SIGCHLD, handle_sigchld);
248 | // 1. 创建套接字
249 | int sockfd;
250 | if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
251 | ERR_EXIT("socket");
252 | }
253 |
254 | // 2. 分配套接字地址
255 | struct sockaddr_in servaddr;
256 | memset(&servaddr, 0, sizeof servaddr);
257 | servaddr.sin_family = AF_INET;
258 | servaddr.sin_port = htons(6666);
259 | // servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
260 | servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
261 | // inet_aton("127.0.0.1", &servaddr.sin_addr);
262 |
263 | // 3. 请求链接
264 | if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof servaddr) < 0) {
265 | ERR_EXIT("connect");
266 | }
267 |
268 | struct sockaddr_in localaddr;
269 | socklen_t addrlen = sizeof localaddr;
270 | if (getsockname(sockfd, (struct sockaddr *) &localaddr, &addrlen) < 0) {
271 | ERR_EXIT("getsockname");
272 | }
273 | printf("id = %s, ", inet_ntoa(localaddr.sin_addr));
274 | printf("port = %d\n", ntohs(localaddr.sin_port));
275 |
276 | // 4. 数据交换
277 | ehco_cli(sockfd);
278 |
279 | // 5. 断开连接
280 | close(sockfd);
281 |
282 |
283 | return 0;
284 | }
--------------------------------------------------------------------------------
/echosrv.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-7-17.
3 | //
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 |
14 | using namespace std;
15 |
16 | #define ERR_EXIT(m) \
17 | do \
18 | { \
19 | perror(m); \
20 | exit(EXIT_FAILURE); \
21 | } while(0);
22 |
23 | int main(int argc, char** argv) {
24 | // 1. 创建套接字
25 | int listenfd;
26 | if ((listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
27 | ERR_EXIT("socket");
28 | }
29 |
30 | // 2. 分配套接字地址
31 | struct sockaddr_in servaddr;
32 | memset(&servaddr, 0, sizeof servaddr);
33 | servaddr.sin_family = AF_INET;
34 | servaddr.sin_port = htons(6666);
35 | servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
36 | // servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
37 | // inet_aton("127.0.0.1", &servaddr.sin_addr);
38 |
39 | int on = 1;
40 | // 确保time_wait状态下同一端口仍可使用
41 | if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on) < 0)
42 | {
43 | ERR_EXIT("setsockopt");
44 | }
45 |
46 | // 3. 绑定套接字地址
47 | if (bind(listenfd, (struct sockaddr*) &servaddr, sizeof servaddr) < 0) {
48 | ERR_EXIT("bind");
49 | }
50 | // 4. 等待连接请求状态
51 | if (listen(listenfd, SOMAXCONN) < 0) {
52 | ERR_EXIT("listen");
53 | }
54 | // 5. 允许连接
55 | struct sockaddr_in peeraddr;
56 | socklen_t peerlen = sizeof peeraddr;
57 | int connfd;
58 | if ((connfd = accept(listenfd, (struct sockaddr *) &peeraddr, &peerlen)) < 0) {
59 | ERR_EXIT("accept");
60 | }
61 |
62 | printf("id = %s, ", inet_ntoa(peeraddr.sin_addr));
63 | printf("port = %d\n", ntohs(peeraddr.sin_port));
64 |
65 | // 6. 数据交换
66 | char recvbuf[1024];
67 | while (1)
68 | {
69 | memset(recvbuf, 0, sizeof recvbuf);
70 | int ret = read(connfd, recvbuf, sizeof recvbuf);
71 | if (ret == 0)
72 | {
73 |
74 | } else
75 | {
76 |
77 | }
78 | fputs(recvbuf, stdout);
79 | write(connfd, recvbuf, ret);
80 | }
81 |
82 | // 7. 断开连接
83 | close(connfd);
84 | close(listenfd);
85 |
86 |
87 |
88 | return 0;
89 | }
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/echosrv2.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-7-17.
3 | //
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 |
14 | using namespace std;
15 |
16 |
17 | #define ERR_EXIT(m) \
18 | do \
19 | { \
20 | perror(m); \
21 | exit(EXIT_FAILURE); \
22 | } while(0);
23 |
24 | void do_service(int connfd)
25 | {
26 | char recvbuf[1024];
27 | while (1)
28 | {
29 | memset(recvbuf, 0, sizeof recvbuf);
30 | int ret = read(connfd, recvbuf, sizeof recvbuf);
31 | if (ret == 0)
32 | {
33 | printf("client close\n");
34 | break;
35 | } else if (ret == -1)
36 | {
37 | ERR_EXIT("read");
38 | }
39 | fputs(recvbuf, stdout);
40 | write(connfd, recvbuf, ret);
41 | }
42 |
43 | }
44 |
45 | int main(int argc, char** argv) {
46 | // 1. 创建套接字
47 | int listenfd;
48 | if ((listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
49 | ERR_EXIT("socket");
50 | }
51 |
52 | // 2. 分配套接字地址
53 | struct sockaddr_in servaddr;
54 | memset(&servaddr, 0, sizeof servaddr);
55 | servaddr.sin_family = AF_INET;
56 | servaddr.sin_port = htons(6666);
57 | servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
58 | // servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
59 | // inet_aton("127.0.0.1", &servaddr.sin_addr);
60 |
61 | int on = 1;
62 | // 确保time_wait状态下同一端口仍可使用
63 | if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on) < 0)
64 | {
65 | ERR_EXIT("setsockopt");
66 | }
67 |
68 | // 3. 绑定套接字地址
69 | if (bind(listenfd, (struct sockaddr*) &servaddr, sizeof servaddr) < 0) {
70 | ERR_EXIT("bind");
71 | }
72 | // 4. 等待连接请求状态
73 | if (listen(listenfd, SOMAXCONN) < 0) {
74 | ERR_EXIT("listen");
75 | }
76 | // 5. 允许连接
77 | struct sockaddr_in peeraddr;
78 | socklen_t peerlen = sizeof peeraddr;
79 |
80 |
81 | // 6. 数据交换
82 | pid_t pid;
83 | while (1)
84 | {
85 | int connfd;
86 | if ((connfd = accept(listenfd, (struct sockaddr *) &peeraddr, &peerlen)) < 0) {
87 | ERR_EXIT("accept");
88 | }
89 |
90 | printf("id = %s, ", inet_ntoa(peeraddr.sin_addr));
91 | printf("port = %d\n", ntohs(peeraddr.sin_port));
92 |
93 | pid = fork();
94 |
95 | if (pid == -1)
96 | {
97 | ERR_EXIT("fork");
98 | }
99 | if (pid == 0) // 子进程
100 | {
101 | close(listenfd);
102 | do_service(connfd);
103 | //printf("child exit\n");
104 | exit(EXIT_SUCCESS);
105 | }
106 | else
107 | {
108 | //printf("parent exit\n");
109 | close(connfd);
110 | }
111 |
112 |
113 | }
114 | // 7. 断开连接
115 | close(listenfd);
116 |
117 |
118 |
119 | return 0;
120 | }
121 |
122 |
--------------------------------------------------------------------------------
/echosrv3.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-7-21.
3 | //
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 |
15 | using namespace std;
16 |
17 | struct packet
18 | {
19 | int len;
20 | char buf[1024];
21 | };
22 |
23 | #define ERR_EXIT(m) \
24 | do \
25 | { \
26 | perror(m); \
27 | exit(EXIT_FAILURE); \
28 | } while(0);
29 |
30 | ssize_t readn(int fd, void *buf, size_t count)
31 | {
32 | size_t nleft = count; // 剩余字节数
33 | ssize_t nread;
34 | char *bufp = (char*) buf;
35 |
36 | while (nleft > 0)
37 | {
38 | nread = read(fd, bufp, nleft);
39 | if (nread < 0)
40 | {
41 | if (errno == EINTR)
42 | {
43 | continue;
44 | }
45 | return -1;
46 | } else if (nread == 0)
47 | {
48 | return count - nleft;
49 | }
50 |
51 | bufp += nread;
52 | nleft -= nread;
53 | }
54 | return count;
55 | }
56 |
57 | ssize_t writen(int fd, const void *buf, size_t count)
58 | {
59 | size_t nleft = count;
60 | ssize_t nwritten;
61 | char* bufp = (char*)buf;
62 |
63 | while (nleft > 0)
64 | {
65 | if ((nwritten = write(fd, bufp, nleft)) < 0)
66 | {
67 | if (errno == EINTR)
68 | {
69 | continue;
70 | }
71 | return -1;
72 | }
73 | else if (nwritten == 0)
74 | {
75 | continue;
76 | }
77 | bufp += nwritten;
78 | nleft -= nwritten;
79 | }
80 | return count;
81 | }
82 |
83 | void do_service(int connfd)
84 | {
85 | // char recvbuf[1024];
86 | struct packet recvbuf;
87 | int n;
88 | while (1)
89 | {
90 | memset(&recvbuf, 0, sizeof recvbuf);
91 | int ret = readn(connfd, &recvbuf.len, 4);
92 | if (ret == -1)
93 | {
94 | ERR_EXIT("read");
95 | }
96 | else if (ret < 4)
97 | {
98 | printf("client close\n");
99 | break;
100 | }
101 |
102 | n = ntohl(recvbuf.len);
103 | ret = readn(connfd, recvbuf.buf, n);
104 | if (ret == -1)
105 | {
106 | ERR_EXIT("read");
107 | }
108 | else if (ret < n)
109 | {
110 | printf("client close\n");
111 | break;
112 | }
113 | fputs(recvbuf.buf, stdout);
114 | writen(connfd, &recvbuf, 4+n);
115 | }
116 |
117 | }
118 |
119 | int main(int argc, char** argv) {
120 | // 1. 创建套接字
121 | int listenfd;
122 | if ((listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
123 | ERR_EXIT("socket");
124 | }
125 |
126 | // 2. 分配套接字地址
127 | struct sockaddr_in servaddr;
128 | memset(&servaddr, 0, sizeof servaddr);
129 | servaddr.sin_family = AF_INET;
130 | servaddr.sin_port = htons(6666);
131 | servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
132 | // servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
133 | // inet_aton("127.0.0.1", &servaddr.sin_addr);
134 |
135 | int on = 1;
136 | // 确保time_wait状态下同一端口仍可使用
137 | if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on) < 0)
138 | {
139 | ERR_EXIT("setsockopt");
140 | }
141 |
142 | // 3. 绑定套接字地址
143 | if (bind(listenfd, (struct sockaddr*) &servaddr, sizeof servaddr) < 0) {
144 | ERR_EXIT("bind");
145 | }
146 | // 4. 等待连接请求状态
147 | if (listen(listenfd, SOMAXCONN) < 0) {
148 | ERR_EXIT("listen");
149 | }
150 | // 5. 允许连接
151 | struct sockaddr_in peeraddr;
152 | socklen_t peerlen = sizeof peeraddr;
153 |
154 |
155 | // 6. 数据交换
156 | pid_t pid;
157 | while (1)
158 | {
159 | int connfd;
160 | if ((connfd = accept(listenfd, (struct sockaddr *) &peeraddr, &peerlen)) < 0) {
161 | ERR_EXIT("accept");
162 | }
163 |
164 | printf("id = %s, ", inet_ntoa(peeraddr.sin_addr));
165 | printf("port = %d\n", ntohs(peeraddr.sin_port));
166 |
167 | pid = fork();
168 |
169 | if (pid == -1)
170 | {
171 | ERR_EXIT("fork");
172 | }
173 | if (pid == 0) // 子进程
174 | {
175 | close(listenfd);
176 | do_service(connfd);
177 | //printf("child exit\n");
178 | exit(EXIT_SUCCESS);
179 | }
180 | else
181 | {
182 | //printf("parent exit\n");
183 | close(connfd);
184 | }
185 |
186 |
187 | }
188 | // 7. 断开连接
189 | close(listenfd);
190 |
191 |
192 |
193 | return 0;
194 | }
--------------------------------------------------------------------------------
/echosrv4.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-6.
3 | //
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 |
15 | using namespace std;
16 |
17 | struct packet
18 | {
19 | int len;
20 | char buf[1024];
21 | };
22 |
23 | #define ERR_EXIT(m) \
24 | do \
25 | { \
26 | perror(m); \
27 | exit(EXIT_FAILURE); \
28 | } while(0);
29 |
30 | ssize_t readn(int fd, void *buf, size_t count)
31 | {
32 | size_t nleft = count; // 剩余字节数
33 | ssize_t nread;
34 | char *bufp = (char*) buf;
35 |
36 | while (nleft > 0)
37 | {
38 | nread = read(fd, bufp, nleft);
39 | if (nread < 0)
40 | {
41 | if (errno == EINTR)
42 | {
43 | continue;
44 | }
45 | return -1;
46 | } else if (nread == 0)
47 | {
48 | return count - nleft;
49 | }
50 |
51 | bufp += nread;
52 | nleft -= nread;
53 | }
54 | return count;
55 | }
56 |
57 | ssize_t writen(int fd, const void *buf, size_t count)
58 | {
59 | size_t nleft = count;
60 | ssize_t nwritten;
61 | char* bufp = (char*)buf;
62 |
63 | while (nleft > 0)
64 | {
65 | if ((nwritten = write(fd, bufp, nleft)) < 0)
66 | {
67 | if (errno == EINTR)
68 | {
69 | continue;
70 | }
71 | return -1;
72 | }
73 | else if (nwritten == 0)
74 | {
75 | continue;
76 | }
77 | bufp += nwritten;
78 | nleft -= nwritten;
79 | }
80 | return count;
81 | }
82 |
83 | ssize_t recv_peek(int sockfd, void *buf, size_t len)
84 | {
85 | while (1)
86 | {
87 | int ret = recv(sockfd, buf, len, MSG_PEEK); // 查看传入消息
88 | if (ret == -1 && errno == EINTR)
89 | {
90 | continue;
91 | }
92 | return ret;
93 | }
94 | }
95 |
96 | ssize_t readline(int sockfd, void *buf, size_t maxline)
97 | {
98 | int ret;
99 | int nread;
100 | char *bufp = (char*)buf; // 当前指针位置
101 | int nleft = maxline;
102 | while (1)
103 | {
104 | ret = recv_peek(sockfd, buf, nleft);
105 | if (ret < 0)
106 | {
107 | return ret;
108 | }
109 | else if (ret == 0)
110 | {
111 | return ret;
112 | }
113 | nread = ret;
114 | int i;
115 | for (i = 0; i < nread; i++)
116 | {
117 | if (bufp[i] == '\n')
118 | {
119 | ret = readn(sockfd, bufp, i+1);
120 | if (ret != i+1)
121 | {
122 | exit(EXIT_FAILURE);
123 | }
124 | return ret;
125 | }
126 | }
127 | if (nread > nleft)
128 | {
129 | exit(EXIT_FAILURE);
130 | }
131 | nleft -= nread;
132 | ret = readn(sockfd, bufp, nread);
133 | if (ret != nread)
134 | {
135 | exit(EXIT_FAILURE);
136 | }
137 | bufp += nread;
138 | }
139 | return -1;
140 | }
141 |
142 | void do_service(int connfd)
143 | {
144 | char recvbuf[1024];
145 | // struct packet recvbuf;
146 | int n;
147 | while (1)
148 | {
149 | memset(recvbuf, 0, sizeof recvbuf);
150 | int ret = readline(connfd, recvbuf, 1024);
151 | if (ret == -1)
152 | {
153 | ERR_EXIT("readline");
154 | }
155 | if (ret == 0)
156 | {
157 | printf("client close\n");
158 | break;
159 | }
160 |
161 | fputs(recvbuf, stdout);
162 | writen(connfd, recvbuf, strlen(recvbuf));
163 | }
164 |
165 | }
166 |
167 | int main(int argc, char** argv) {
168 | // 1. 创建套接字
169 | int listenfd;
170 | if ((listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
171 | ERR_EXIT("socket");
172 | }
173 |
174 | // 2. 分配套接字地址
175 | struct sockaddr_in servaddr;
176 | memset(&servaddr, 0, sizeof servaddr);
177 | servaddr.sin_family = AF_INET;
178 | servaddr.sin_port = htons(6666);
179 | servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
180 | // servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
181 | // inet_aton("127.0.0.1", &servaddr.sin_addr);
182 |
183 | int on = 1;
184 | // 确保time_wait状态下同一端口仍可使用
185 | if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on) < 0)
186 | {
187 | ERR_EXIT("setsockopt");
188 | }
189 |
190 | // 3. 绑定套接字地址
191 | if (bind(listenfd, (struct sockaddr*) &servaddr, sizeof servaddr) < 0) {
192 | ERR_EXIT("bind");
193 | }
194 | // 4. 等待连接请求状态
195 | if (listen(listenfd, SOMAXCONN) < 0) {
196 | ERR_EXIT("listen");
197 | }
198 | // 5. 允许连接
199 | struct sockaddr_in peeraddr;
200 | socklen_t peerlen = sizeof peeraddr;
201 |
202 |
203 | // 6. 数据交换
204 | pid_t pid;
205 | while (1)
206 | {
207 | int connfd;
208 | if ((connfd = accept(listenfd, (struct sockaddr *) &peeraddr, &peerlen)) < 0) {
209 | ERR_EXIT("accept");
210 | }
211 |
212 | printf("id = %s, ", inet_ntoa(peeraddr.sin_addr));
213 | printf("port = %d\n", ntohs(peeraddr.sin_port));
214 |
215 | pid = fork();
216 |
217 | if (pid == -1)
218 | {
219 | ERR_EXIT("fork");
220 | }
221 | if (pid == 0) // 子进程
222 | {
223 | close(listenfd);
224 | do_service(connfd);
225 | //printf("child exit\n");
226 | exit(EXIT_SUCCESS);
227 | }
228 | else
229 | {
230 | //printf("parent exit\n");
231 | close(connfd);
232 | }
233 |
234 |
235 | }
236 | // 7. 断开连接
237 | close(listenfd);
238 |
239 |
240 |
241 | return 0;
242 | }
--------------------------------------------------------------------------------
/echosrv5.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-6.
3 | //
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 |
15 | using namespace std;
16 |
17 | struct packet
18 | {
19 | int len;
20 | char buf[1024];
21 | };
22 |
23 | #define ERR_EXIT(m) \
24 | do \
25 | { \
26 | perror(m); \
27 | exit(EXIT_FAILURE); \
28 | } while(0);
29 |
30 | ssize_t readn(int fd, void *buf, size_t count)
31 | {
32 | size_t nleft = count; // 剩余字节数
33 | ssize_t nread;
34 | char *bufp = (char*) buf;
35 |
36 | while (nleft > 0)
37 | {
38 | nread = read(fd, bufp, nleft);
39 | if (nread < 0)
40 | {
41 | if (errno == EINTR)
42 | {
43 | continue;
44 | }
45 | return -1;
46 | } else if (nread == 0)
47 | {
48 | return count - nleft;
49 | }
50 |
51 | bufp += nread;
52 | nleft -= nread;
53 | }
54 | return count;
55 | }
56 |
57 | ssize_t writen(int fd, const void *buf, size_t count)
58 | {
59 | size_t nleft = count;
60 | ssize_t nwritten;
61 | char* bufp = (char*)buf;
62 |
63 | while (nleft > 0)
64 | {
65 | if ((nwritten = write(fd, bufp, nleft)) < 0)
66 | {
67 | if (errno == EINTR)
68 | {
69 | continue;
70 | }
71 | return -1;
72 | }
73 | else if (nwritten == 0)
74 | {
75 | continue;
76 | }
77 | bufp += nwritten;
78 | nleft -= nwritten;
79 | }
80 | return count;
81 | }
82 |
83 | ssize_t recv_peek(int sockfd, void *buf, size_t len)
84 | {
85 | while (1)
86 | {
87 | int ret = recv(sockfd, buf, len, MSG_PEEK); // 查看传入消息
88 | if (ret == -1 && errno == EINTR)
89 | {
90 | continue;
91 | }
92 | return ret;
93 | }
94 | }
95 |
96 | ssize_t readline(int sockfd, void *buf, size_t maxline)
97 | {
98 | int ret;
99 | int nread;
100 | char *bufp = (char*)buf; // 当前指针位置
101 | int nleft = maxline;
102 | while (1)
103 | {
104 | ret = recv_peek(sockfd, buf, nleft);
105 | if (ret < 0)
106 | {
107 | return ret;
108 | }
109 | else if (ret == 0)
110 | {
111 | return ret;
112 | }
113 | nread = ret;
114 | int i;
115 | for (i = 0; i < nread; i++)
116 | {
117 | if (bufp[i] == '\n')
118 | {
119 | ret = readn(sockfd, bufp, i+1);
120 | if (ret != i+1)
121 | {
122 | exit(EXIT_FAILURE);
123 | }
124 | return ret;
125 | }
126 | }
127 | if (nread > nleft)
128 | {
129 | exit(EXIT_FAILURE);
130 | }
131 | nleft -= nread;
132 | ret = readn(sockfd, bufp, nread);
133 | if (ret != nread)
134 | {
135 | exit(EXIT_FAILURE);
136 | }
137 | bufp += nread;
138 | }
139 | return -1;
140 | }
141 |
142 | void echo_srv(int connfd)
143 | {
144 | char recvbuf[1024];
145 | // struct packet recvbuf;
146 | int n;
147 | while (1)
148 | {
149 | memset(recvbuf, 0, sizeof recvbuf);
150 | int ret = readline(connfd, recvbuf, 1024);
151 | if (ret == -1)
152 | {
153 | ERR_EXIT("readline");
154 | }
155 | if (ret == 0)
156 | {
157 | printf("client close\n");
158 | break;
159 | }
160 |
161 | fputs(recvbuf, stdout);
162 | writen(connfd, recvbuf, strlen(recvbuf));
163 | }
164 |
165 | }
166 |
167 | int main(int argc, char** argv) {
168 | // 1. 创建套接字
169 | int listenfd;
170 | if ((listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
171 | ERR_EXIT("socket");
172 | }
173 |
174 | // 2. 分配套接字地址
175 | struct sockaddr_in servaddr;
176 | memset(&servaddr, 0, sizeof servaddr);
177 | servaddr.sin_family = AF_INET;
178 | servaddr.sin_port = htons(6666);
179 | servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
180 | // servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
181 | // inet_aton("127.0.0.1", &servaddr.sin_addr);
182 |
183 | int on = 1;
184 | // 确保time_wait状态下同一端口仍可使用
185 | if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on) < 0) {
186 | ERR_EXIT("setsockopt");
187 | }
188 |
189 | // 3. 绑定套接字地址
190 | if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof servaddr) < 0) {
191 | ERR_EXIT("bind");
192 | }
193 | // 4. 等待连接请求状态
194 | if (listen(listenfd, SOMAXCONN) < 0) {
195 | ERR_EXIT("listen");
196 | }
197 | // 5. 允许连接
198 | struct sockaddr_in peeraddr;
199 | socklen_t peerlen = sizeof peeraddr;
200 |
201 |
202 | // 6. 数据交换
203 | pid_t pid;
204 | while (1) {
205 | int connfd;
206 | if ((connfd = accept(listenfd, (struct sockaddr *) &peeraddr, &peerlen)) < 0) {
207 | ERR_EXIT("accept");
208 | }
209 |
210 | printf("id = %s, ", inet_ntoa(peeraddr.sin_addr));
211 | printf("port = %d\n", ntohs(peeraddr.sin_port));
212 |
213 | pid = fork();
214 |
215 | if (pid == -1) {
216 | ERR_EXIT("fork");
217 | }
218 | if (pid == 0) // 子进程
219 | {
220 | close(listenfd);
221 | echo_srv(connfd);
222 | //printf("child exit\n");
223 | exit(EXIT_SUCCESS);
224 | } else {
225 | //printf("parent exit\n");
226 | close(connfd);
227 | }
228 |
229 |
230 | }
231 | // 7. 断开连接
232 | close(listenfd);
233 |
234 |
235 | return 0;
236 | }
--------------------------------------------------------------------------------
/echosrv6.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-6.
3 | //
4 |
5 | // socket编程 8 select模型
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 |
17 | using namespace std;
18 |
19 | struct packet
20 | {
21 | int len;
22 | char buf[1024];
23 | };
24 |
25 | #define ERR_EXIT(m) \
26 | do \
27 | { \
28 | perror(m); \
29 | exit(EXIT_FAILURE); \
30 | } while(0);
31 |
32 | ssize_t readn(int fd, void *buf, size_t count)
33 | {
34 | size_t nleft = count; // 剩余字节数
35 | ssize_t nread;
36 | char *bufp = (char*) buf;
37 |
38 | while (nleft > 0)
39 | {
40 | nread = read(fd, bufp, nleft);
41 | if (nread < 0)
42 | {
43 | if (errno == EINTR)
44 | {
45 | continue;
46 | }
47 | return -1;
48 | } else if (nread == 0)
49 | {
50 | return count - nleft;
51 | }
52 |
53 | bufp += nread;
54 | nleft -= nread;
55 | }
56 | return count;
57 | }
58 |
59 | ssize_t writen(int fd, const void *buf, size_t count)
60 | {
61 | size_t nleft = count;
62 | ssize_t nwritten;
63 | char* bufp = (char*)buf;
64 |
65 | while (nleft > 0)
66 | {
67 | if ((nwritten = write(fd, bufp, nleft)) < 0)
68 | {
69 | if (errno == EINTR)
70 | {
71 | continue;
72 | }
73 | return -1;
74 | }
75 | else if (nwritten == 0)
76 | {
77 | continue;
78 | }
79 | bufp += nwritten;
80 | nleft -= nwritten;
81 | }
82 | return count;
83 | }
84 |
85 | ssize_t recv_peek(int sockfd, void *buf, size_t len)
86 | {
87 | while (1)
88 | {
89 | int ret = recv(sockfd, buf, len, MSG_PEEK); // 查看传入消息
90 | if (ret == -1 && errno == EINTR)
91 | {
92 | continue;
93 | }
94 | return ret;
95 | }
96 | }
97 |
98 | ssize_t readline(int sockfd, void *buf, size_t maxline)
99 | {
100 | int ret;
101 | int nread;
102 | char *bufp = (char*)buf; // 当前指针位置
103 | int nleft = maxline;
104 | while (1)
105 | {
106 | ret = recv_peek(sockfd, buf, nleft);
107 | if (ret < 0)
108 | {
109 | return ret;
110 | }
111 | else if (ret == 0)
112 | {
113 | return ret;
114 | }
115 | nread = ret;
116 | int i;
117 | for (i = 0; i < nread; i++)
118 | {
119 | if (bufp[i] == '\n')
120 | {
121 | ret = readn(sockfd, bufp, i+1);
122 | if (ret != i+1)
123 | {
124 | exit(EXIT_FAILURE);
125 | }
126 | return ret;
127 | }
128 | }
129 | if (nread > nleft)
130 | {
131 | exit(EXIT_FAILURE);
132 | }
133 | nleft -= nread;
134 | ret = readn(sockfd, bufp, nread);
135 | if (ret != nread)
136 | {
137 | exit(EXIT_FAILURE);
138 | }
139 | bufp += nread;
140 | }
141 | return -1;
142 | }
143 |
144 | void echo_srv(int connfd)
145 | {
146 | char recvbuf[1024];
147 | // struct packet recvbuf;
148 | int n;
149 | while (1)
150 | {
151 | memset(recvbuf, 0, sizeof recvbuf);
152 | int ret = readline(connfd, recvbuf, 1024);
153 | if (ret == -1)
154 | {
155 | ERR_EXIT("readline");
156 | }
157 | if (ret == 0)
158 | {
159 | printf("client close\n");
160 | break;
161 | }
162 |
163 | fputs(recvbuf, stdout);
164 | writen(connfd, recvbuf, strlen(recvbuf));
165 | }
166 |
167 | }
168 |
169 | int main(int argc, char** argv) {
170 | // 1. 创建套接字
171 | int listenfd;
172 | if ((listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
173 | ERR_EXIT("socket");
174 | }
175 |
176 | // 2. 分配套接字地址
177 | struct sockaddr_in servaddr;
178 | memset(&servaddr, 0, sizeof servaddr);
179 | servaddr.sin_family = AF_INET;
180 | servaddr.sin_port = htons(6666);
181 | servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
182 | // servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
183 | // inet_aton("127.0.0.1", &servaddr.sin_addr);
184 |
185 | int on = 1;
186 | // 确保time_wait状态下同一端口仍可使用
187 | if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on) < 0) {
188 | ERR_EXIT("setsockopt");
189 | }
190 |
191 | // 3. 绑定套接字地址
192 | if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof servaddr) < 0) {
193 | ERR_EXIT("bind");
194 | }
195 | // 4. 等待连接请求状态
196 | if (listen(listenfd, SOMAXCONN) < 0) {
197 | ERR_EXIT("listen");
198 | }
199 | // 5. 允许连接
200 | struct sockaddr_in peeraddr;
201 | socklen_t peerlen = sizeof peeraddr;
202 |
203 |
204 | // 6. 数据交换
205 | pid_t pid;
206 | while (1) {
207 | int connfd;
208 | if ((connfd = accept(listenfd, (struct sockaddr *) &peeraddr, &peerlen)) < 0) {
209 | ERR_EXIT("accept");
210 | }
211 |
212 | printf("id = %s, ", inet_ntoa(peeraddr.sin_addr));
213 | printf("port = %d\n", ntohs(peeraddr.sin_port));
214 |
215 | pid = fork();
216 |
217 | if (pid == -1) {
218 | ERR_EXIT("fork");
219 | }
220 | if (pid == 0) // 子进程
221 | {
222 | close(listenfd);
223 | echo_srv(connfd);
224 | //printf("child exit\n");
225 | exit(EXIT_SUCCESS);
226 | } else {
227 | //printf("parent exit\n");
228 | close(connfd);
229 | }
230 |
231 |
232 | }
233 | // 7. 断开连接
234 | close(listenfd);
235 |
236 |
237 | return 0;
238 | }
--------------------------------------------------------------------------------
/echosrv7.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-7.
3 | //
4 |
5 | // socket编程 9
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 |
17 | using namespace std;
18 |
19 | struct packet
20 | {
21 | int len;
22 | char buf[1024];
23 | };
24 |
25 | #define ERR_EXIT(m) \
26 | do \
27 | { \
28 | perror(m); \
29 | exit(EXIT_FAILURE); \
30 | } while(0);
31 |
32 | ssize_t readn(int fd, void *buf, size_t count)
33 | {
34 | size_t nleft = count; // 剩余字节数
35 | ssize_t nread;
36 | char *bufp = (char*) buf;
37 |
38 | while (nleft > 0)
39 | {
40 | nread = read(fd, bufp, nleft);
41 | if (nread < 0)
42 | {
43 | if (errno == EINTR)
44 | {
45 | continue;
46 | }
47 | return -1;
48 | } else if (nread == 0)
49 | {
50 | return count - nleft;
51 | }
52 |
53 | bufp += nread;
54 | nleft -= nread;
55 | }
56 | return count;
57 | }
58 |
59 | ssize_t writen(int fd, const void *buf, size_t count)
60 | {
61 | size_t nleft = count;
62 | ssize_t nwritten;
63 | char* bufp = (char*)buf;
64 |
65 | while (nleft > 0)
66 | {
67 | if ((nwritten = write(fd, bufp, nleft)) < 0)
68 | {
69 | if (errno == EINTR)
70 | {
71 | continue;
72 | }
73 | return -1;
74 | }
75 | else if (nwritten == 0)
76 | {
77 | continue;
78 | }
79 | bufp += nwritten;
80 | nleft -= nwritten;
81 | }
82 | return count;
83 | }
84 |
85 | ssize_t recv_peek(int sockfd, void *buf, size_t len)
86 | {
87 | while (1)
88 | {
89 | int ret = recv(sockfd, buf, len, MSG_PEEK); // 查看传入消息
90 | if (ret == -1 && errno == EINTR)
91 | {
92 | continue;
93 | }
94 | return ret;
95 | }
96 | }
97 |
98 | ssize_t readline(int sockfd, void *buf, size_t maxline)
99 | {
100 | int ret;
101 | int nread;
102 | char *bufp = (char*)buf; // 当前指针位置
103 | int nleft = maxline;
104 | while (1)
105 | {
106 | ret = recv_peek(sockfd, buf, nleft);
107 | if (ret < 0)
108 | {
109 | return ret;
110 | }
111 | else if (ret == 0)
112 | {
113 | return ret;
114 | }
115 | nread = ret;
116 | int i;
117 | for (i = 0; i < nread; i++)
118 | {
119 | if (bufp[i] == '\n')
120 | {
121 | ret = readn(sockfd, bufp, i+1);
122 | if (ret != i+1)
123 | {
124 | exit(EXIT_FAILURE);
125 | }
126 | return ret;
127 | }
128 | }
129 | if (nread > nleft)
130 | {
131 | exit(EXIT_FAILURE);
132 | }
133 | nleft -= nread;
134 | ret = readn(sockfd, bufp, nread);
135 | if (ret != nread)
136 | {
137 | exit(EXIT_FAILURE);
138 | }
139 | bufp += nread;
140 | }
141 | return -1;
142 | }
143 |
144 | void echo_srv(int connfd)
145 | {
146 | char recvbuf[1024];
147 | // struct packet recvbuf;
148 | int n;
149 | while (1)
150 | {
151 | memset(recvbuf, 0, sizeof recvbuf);
152 | int ret = readline(connfd, recvbuf, 1024);
153 | if (ret == -1)
154 | {
155 | ERR_EXIT("readline");
156 | }
157 | if (ret == 0)
158 | {
159 | printf("client close\n");
160 | break;
161 | }
162 |
163 | fputs(recvbuf, stdout);
164 | writen(connfd, recvbuf, strlen(recvbuf));
165 | }
166 |
167 | }
168 |
169 | int main(int argc, char** argv) {
170 | // 1. 创建套接字
171 | int listenfd;
172 | if ((listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
173 | ERR_EXIT("socket");
174 | }
175 |
176 | // 2. 分配套接字地址
177 | struct sockaddr_in servaddr;
178 | memset(&servaddr, 0, sizeof servaddr);
179 | servaddr.sin_family = AF_INET;
180 | servaddr.sin_port = htons(6666);
181 | servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
182 | // servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
183 | // inet_aton("127.0.0.1", &servaddr.sin_addr);
184 |
185 | int on = 1;
186 | // 确保time_wait状态下同一端口仍可使用
187 | if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on) < 0) {
188 | ERR_EXIT("setsockopt");
189 | }
190 |
191 | // 3. 绑定套接字地址
192 | if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof servaddr) < 0) {
193 | ERR_EXIT("bind");
194 | }
195 | // 4. 等待连接请求状态
196 | if (listen(listenfd, SOMAXCONN) < 0) {
197 | ERR_EXIT("listen");
198 | }
199 | // 5. 允许连接
200 | struct sockaddr_in peeraddr;
201 | socklen_t peerlen;
202 |
203 |
204 | // 6. 数据交换
205 | int nready;
206 | int maxfd = listenfd;
207 | fd_set rset;
208 | fd_set allset;
209 | FD_ZERO(&rset);
210 | FD_ZERO(&allset);
211 | FD_SET(listenfd, &allset);
212 | int connfd;
213 | int i;
214 | int client[FD_SETSIZE];
215 | int ret;
216 | int Max = 0;
217 | memset(client, -1, sizeof(client));
218 | while (1)
219 | {
220 | rset = allset;
221 | nready = select(maxfd + 1, &rset, NULL, NULL, NULL);
222 | if (nready == -1)
223 | {
224 | if (errno == EINTR)
225 | {
226 | continue;
227 | }
228 | ERR_EXIT("select");
229 | }
230 |
231 | if (nready == 0)
232 | {
233 | continue;
234 | }
235 |
236 | if (FD_ISSET(listenfd, &rset))
237 | {
238 | peerlen = sizeof(peeraddr);
239 | connfd = accept(listenfd, (struct sockaddr *)&peeraddr, &peerlen);
240 | if (connfd == -1)
241 | {
242 | ERR_EXIT("accept");
243 | }
244 | for (i = 0; i < FD_SETSIZE; i++)
245 | {
246 | if (client[i] < 0)
247 | {
248 | client[i] = connfd;
249 | break;
250 | }
251 | }
252 | if (i == FD_SETSIZE)
253 | {
254 | fprintf(stderr, "too many clients\n");
255 | exit(EXIT_FAILURE);
256 | }
257 | printf("id = %s, ", inet_ntoa(peeraddr.sin_addr));
258 | printf("port = %d\n", ntohs(peeraddr.sin_port));
259 | FD_SET(connfd, &allset);
260 | Max++;
261 | maxfd = max(maxfd, connfd);
262 | if (--nready <= 0)
263 | {
264 | continue;
265 | }
266 | }
267 | for (i = 0; i < Max; ++i)
268 | {
269 | connfd = client[i];
270 | if (connfd == -1)
271 | {
272 | continue;
273 | }
274 | if (FD_ISSET(connfd, &rset))
275 | {
276 | char recvbuf[1024] = {0};
277 | ret = readline(connfd, recvbuf, 1024);
278 | if (ret == -1)
279 | {
280 | ERR_EXIT("readline");
281 | }
282 | if (ret == 0)
283 | {
284 | printf("client close\n");
285 | client[i] = -1;
286 | FD_CLR(connfd, &allset);
287 | Max--;
288 | }
289 | fputs(recvbuf, stdout);
290 | //sleep(4);
291 | writen(connfd, recvbuf, strlen(recvbuf));
292 | if (--nready <= 0)
293 | {
294 | break;
295 | }
296 | };
297 | }
298 | }
299 | // pid_t pid;
300 | // while (1) {
301 | // int connfd;
302 | // if ((connfd = accept(listenfd, (struct sockaddr *) &peeraddr, &peerlen)) < 0) {
303 | // ERR_EXIT("accept");
304 | // }
305 | //
306 | // printf("id = %s, ", inet_ntoa(peeraddr.sin_addr));
307 | // printf("port = %d\n", ntohs(peeraddr.sin_port));
308 | //
309 | // pid = fork();
310 | //
311 | // if (pid == -1) {
312 | // ERR_EXIT("fork");
313 | // }
314 | // if (pid == 0) // 子进程
315 | // {
316 | // close(listenfd);
317 | // echo_srv(connfd);
318 | // //printf("child exit\n");
319 | // exit(EXIT_SUCCESS);
320 | // } else {
321 | // //printf("parent exit\n");
322 | // close(connfd);
323 | // }
324 | //
325 | //
326 | // }
327 | // 7. 断开连接
328 | close(listenfd);
329 |
330 |
331 | return 0;
332 | }
--------------------------------------------------------------------------------
/epollsrv.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-7.
3 | //
4 |
5 | // socket编程 13 epoll 模型
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 |
22 |
23 | using namespace std;
24 |
25 | typedef vector EventList;
26 |
27 | struct packet
28 | {
29 | int len;
30 | char buf[1024];
31 | };
32 |
33 | #define ERR_EXIT(m) \
34 | do \
35 | { \
36 | perror(m); \
37 | exit(EXIT_FAILURE); \
38 | } while(0);
39 |
40 | ssize_t readn(int fd, void *buf, size_t count)
41 | {
42 | size_t nleft = count; // 剩余字节数
43 | ssize_t nread;
44 | char *bufp = (char*) buf;
45 |
46 | while (nleft > 0)
47 | {
48 | nread = read(fd, bufp, nleft);
49 | if (nread < 0)
50 | {
51 | if (errno == EINTR)
52 | {
53 | continue;
54 | }
55 | return -1;
56 | } else if (nread == 0)
57 | {
58 | return count - nleft;
59 | }
60 |
61 | bufp += nread;
62 | nleft -= nread;
63 | }
64 | return count;
65 | }
66 |
67 | ssize_t writen(int fd, const void *buf, size_t count)
68 | {
69 | size_t nleft = count;
70 | ssize_t nwritten;
71 | char* bufp = (char*)buf;
72 |
73 | while (nleft > 0)
74 | {
75 | if ((nwritten = write(fd, bufp, nleft)) < 0)
76 | {
77 | if (errno == EINTR)
78 | {
79 | continue;
80 | }
81 | return -1;
82 | }
83 | else if (nwritten == 0)
84 | {
85 | continue;
86 | }
87 | bufp += nwritten;
88 | nleft -= nwritten;
89 | }
90 | return count;
91 | }
92 |
93 | ssize_t recv_peek(int sockfd, void *buf, size_t len)
94 | {
95 | while (1)
96 | {
97 | int ret = recv(sockfd, buf, len, MSG_PEEK); // 查看传入消息
98 | if (ret == -1 && errno == EINTR)
99 | {
100 | continue;
101 | }
102 | return ret;
103 | }
104 | }
105 |
106 | ssize_t readline(int sockfd, void *buf, size_t maxline)
107 | {
108 | int ret;
109 | int nread;
110 | char *bufp = (char*)buf; // 当前指针位置
111 | int nleft = maxline;
112 | while (1)
113 | {
114 | ret = recv_peek(sockfd, buf, nleft);
115 | if (ret < 0)
116 | {
117 | return ret;
118 | }
119 | else if (ret == 0)
120 | {
121 | return ret;
122 | }
123 | nread = ret;
124 | int i;
125 | for (i = 0; i < nread; i++)
126 | {
127 | if (bufp[i] == '\n')
128 | {
129 | ret = readn(sockfd, bufp, i+1);
130 | if (ret != i+1)
131 | {
132 | exit(EXIT_FAILURE);
133 | }
134 | return ret;
135 | }
136 | }
137 | if (nread > nleft)
138 | {
139 | exit(EXIT_FAILURE);
140 | }
141 | nleft -= nread;
142 | ret = readn(sockfd, bufp, nread);
143 | if (ret != nread)
144 | {
145 | exit(EXIT_FAILURE);
146 | }
147 | bufp += nread;
148 | }
149 | return -1;
150 | }
151 |
152 | void echo_srv(int connfd)
153 | {
154 | char recvbuf[1024];
155 | // struct packet recvbuf;
156 | int n;
157 | while (1)
158 | {
159 | memset(recvbuf, 0, sizeof recvbuf);
160 | int ret = readline(connfd, recvbuf, 1024);
161 | if (ret == -1)
162 | {
163 | ERR_EXIT("readline");
164 | }
165 | if (ret == 0)
166 | {
167 | printf("client close\n");
168 | break;
169 | }
170 |
171 | fputs(recvbuf, stdout);
172 | writen(connfd, recvbuf, strlen(recvbuf));
173 | }
174 |
175 | }
176 |
177 | void activate_nonblock(int fd)
178 | {
179 | int ret;
180 | int flags = fcntl(fd, F_GETFL);
181 | if(flags == -1)
182 | ERR_EXIT("fcntl");
183 | flags |= O_NONBLOCK;
184 | ret = fcntl(fd, F_SETFL, flags);
185 | if(ret == -1)
186 | ERR_EXIT("fcntl");
187 | }
188 |
189 | int main(int argc, char** argv) {
190 | // 1. 创建套接字
191 | int listenfd;
192 | if ((listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
193 | ERR_EXIT("socket");
194 | }
195 |
196 | // 2. 分配套接字地址
197 | struct sockaddr_in servaddr;
198 | memset(&servaddr, 0, sizeof servaddr);
199 | servaddr.sin_family = AF_INET;
200 | servaddr.sin_port = htons(6666);
201 | servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
202 | // servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
203 | // inet_aton("127.0.0.1", &servaddr.sin_addr);
204 |
205 | int on = 1;
206 | // 确保time_wait状态下同一端口仍可使用
207 | if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on) < 0) {
208 | ERR_EXIT("setsockopt");
209 | }
210 |
211 | // 3. 绑定套接字地址
212 | if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof servaddr) < 0) {
213 | ERR_EXIT("bind");
214 | }
215 | // 4. 等待连接请求状态
216 | if (listen(listenfd, SOMAXCONN) < 0) {
217 | ERR_EXIT("listen");
218 | }
219 | // 5. 允许连接
220 | struct sockaddr_in peeraddr;
221 | socklen_t peerlen;
222 |
223 |
224 | // 6. 数据交换
225 | int nready;
226 | int connfd;
227 | int i;
228 | vector clients;
229 | int epollfd;
230 | epollfd = epoll_create1(EPOLL_CLOEXEC); // 创建一个多路复用的实例
231 |
232 | struct epoll_event event;
233 | event.data.fd = listenfd;
234 | event.events = EPOLLIN | EPOLLET;
235 | epoll_ctl(epollfd, EPOLL_CTL_ADD, listenfd, &event);
236 |
237 | EventList events(16);
238 |
239 | while (1)
240 | {
241 | // 等侍注册在epfd上的socket fd的事件的发生,如果发生则将发生的sokct fd和事件类型放入到events数组中
242 | nready = epoll_wait(epollfd, &*events.begin(), static_cast(events.size()), -1); // 用于轮询I/O事件的发生
243 | if (nready == -1)
244 | {
245 | if (errno == EINTR)
246 | {
247 | continue;
248 | }
249 | ERR_EXIT("epoll_wait");
250 | }
251 |
252 | if (nready == 0)
253 | {
254 | continue;
255 | }
256 |
257 | if ((size_t)nready == events.size())
258 | {
259 | events.resize(events.size()*2);
260 | }
261 |
262 | for (i = 0; i < nready; ++i)
263 | {
264 | if (events[i].data.fd == listenfd)
265 | {
266 | peerlen = sizeof(peeraddr);
267 | connfd = accept(listenfd, (struct sockaddr*)&peeraddr, &peerlen);
268 | if (connfd == -1)
269 | {
270 | ERR_EXIT("accept");
271 | }
272 | printf("id = %s, ", inet_ntoa(peeraddr.sin_addr));
273 | printf("port = %d\n", ntohs(peeraddr.sin_port));
274 | clients.push_back(connfd);
275 | activate_nonblock(connfd);
276 |
277 | event.data.fd = connfd;
278 | event.events = EPOLLIN | EPOLLET;
279 | epoll_ctl(epollfd, EPOLL_CTL_ADD, connfd, &event);
280 |
281 | } else if (events[i].events & EPOLLIN)
282 | {
283 | connfd = events[i].data.fd;
284 | if (connfd < 0)
285 | {
286 | continue;
287 | }
288 | char recvbuf[1024];
289 | int ret = readline(connfd, recvbuf, sizeof(recvbuf));
290 | if (ret == -1)
291 | {
292 | ERR_EXIT("readline");
293 | }
294 | if (ret == 0)
295 | {
296 | printf("client close\n");
297 | close(connfd);
298 |
299 | event = events[i];
300 | epoll_ctl(epollfd, EPOLL_CTL_DEL, connfd, &event);
301 | clients.erase(
302 | remove_if(clients.begin(), clients.end(), [connfd](int n){return n == connfd;}),
303 | clients.end());
304 | }
305 | fputs(recvbuf, stdout);
306 | writen(connfd, recvbuf, strlen(recvbuf));
307 | memset(recvbuf, 0, sizeof recvbuf);
308 | }
309 | }
310 |
311 | }
312 | // 7. 断开连接
313 | close(listenfd);
314 | return 0;
315 | }
316 |
--------------------------------------------------------------------------------
/gethostbyname_test.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by jxq on 19-8-6.
3 | //
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | #define ERR_EXIT(m) \
16 | do \
17 | { \
18 | perror(m); \
19 | exit(EXIT_FAILURE); \
20 | } while (0);
21 |
22 | int getlocalip(char *ip)
23 | {
24 | char host[100] = {0};
25 | if (gethostname(host, sizeof host) < 0)
26 | {
27 | ERR_EXIT("gethostname");
28 | }
29 |
30 | struct hostent *hp;
31 | if ((hp = gethostbyname(host)) == NULL)
32 | {
33 | ERR_EXIT("gethostbyname");
34 | }
35 | strcpy(ip, inet_ntoa(*(struct in_addr*)hp->h_addr_list[0]));
36 | return 0;
37 | }
38 |
39 | int main(void)
40 | {
41 | // char host[100] = {0};
42 | // if (gethostname(host, sizeof host) < 0)
43 | // {
44 | // ERR_EXIT("gethostname");
45 | // }
46 | //
47 | // struct hostent *hp;
48 | // if ((hp = gethostbyname(host)) == NULL)
49 | // {
50 | // ERR_EXIT("gethostbyname");
51 | // }
52 | // int i = 0;
53 | // while (hp->h_addr_list[i] != NULL)
54 | // {
55 | // printf("%s\n", inet_ntoa(*(struct in_addr*)hp->h_addr_list[i]));
56 | // ++i;
57 | // }
58 |
59 | char ip[16] = {0};
60 | getlocalip(ip);
61 | printf("localip = %s\n", ip);
62 |
63 | return 0;
64 | }
65 |
--------------------------------------------------------------------------------
/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | using namespace std;
7 |
8 | // 该文件为原始文件 具体实现在各个文件中
9 |
10 | #define ERR_EXIF(m) \
11 | do \
12 | { \
13 | perror(m); \
14 | exit(EXIT_FAILURE); \
15 | } while(0);
16 |
17 | char* trim(char* cmdline)
18 | {
19 | char* s = cmdline;
20 | while (*s == ' ')
21 | {
22 | s++;
23 | }
24 |
25 | char* e = s;
26 | int len = 0;
27 | while ((strcmp(e, "") != 0) && *e != ' ')
28 | {
29 | len++;
30 | e++;
31 | }
32 | char* res = new char[len];
33 | memcpy(res, s, len);
34 | return res;
35 | }
36 |
37 | vector getcmd(char* cmdline) {
38 | vector res;
39 | char *s = trim(cmdline);
40 | if (strcmp(s, "") == 0) {
41 | return res;
42 | }
43 | int len = 0;
44 | char *temp;
45 | char *tmp ;
46 | int count = 3;
47 | while (count--) {
48 | s = trim(cmdline);
49 | if (strcmp(s, "") == 0) {
50 | return res;
51 | }
52 | len = 0;
53 | temp = s;
54 | tmp = new char[100];
55 | while ((strcmp(temp, "") != 0) && *temp != ' ') {
56 | len++;
57 | temp++;
58 | }
59 | memcpy(tmp, s, len);
60 | res.push_back(tmp);
61 | cmdline = cmdline + len;
62 | while ((strcmp(cmdline, "") != 0) && *cmdline == ' ')
63 | {
64 | cmdline++;
65 | }
66 | }
67 | return res;
68 | }
69 |
70 | int main() {
71 | char* p;
72 | char* cmdline = new char[100];
73 | while (cin.getline(cmdline, 100))
74 | {
75 | vector