-
Notifications
You must be signed in to change notification settings - Fork 46
Expand file tree
/
Copy pathechocli3.cpp
More file actions
153 lines (132 loc) · 3.25 KB
/
echocli3.cpp
File metadata and controls
153 lines (132 loc) · 3.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//
// Created by jxq on 19-7-21.
//
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
using namespace std;
struct packet
{
int len;
char buf[1024];
};
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while(0);
ssize_t readn(int fd, void *buf, size_t count)
{
size_t nleft = count; // 剩余字节数
ssize_t nread;
char *bufp = (char*) buf;
while (nleft > 0)
{
nread = read(fd, bufp, nleft);
if (nread < 0)
{
if (errno == EINTR)
{
continue;
}
return -1;
} else if (nread == 0)
{
return count - nleft;
}
bufp += nread;
nleft -= nread;
}
return count;
}
ssize_t writen(int fd, const void *buf, size_t count)
{
size_t nleft = count;
ssize_t nwritten;
char* bufp = (char*)buf;
while (nleft > 0)
{
if ((nwritten = write(fd, bufp, nleft)) < 0)
{
if (errno == EINTR)
{
continue;
}
return -1;
}
else if (nwritten == 0)
{
continue;
}
bufp += nwritten;
nleft -= nwritten;
}
return count;
}
int main(int argc, char** argv) {
// 1. 创建套接字
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
ERR_EXIT("socket");
}
// 2. 分配套接字地址
struct sockaddr_in servaddr;
memset(&servaddr, 0, sizeof servaddr);
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(6666);
// servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
// inet_aton("127.0.0.1", &servaddr.sin_addr);
// 3. 请求链接
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof servaddr) < 0) {
ERR_EXIT("connect");
}
// 4. 数据交换
// char recvbuf[1024];
// char sendbuf[1024];
struct packet recvbuf;
struct packet sendbuf;
memset(&recvbuf, 0, sizeof recvbuf);
memset(&sendbuf, 0, sizeof sendbuf);
int n = 0;
while (fgets(sendbuf.buf, sizeof sendbuf.buf, stdin) != NULL) // 键盘输入获取
{
n = strlen(sendbuf.buf);
sendbuf.len = htonl(n); // 主机字节序转换为网络字节序
writen(sockfd, &sendbuf, 4+n); // 写入服务器
int ret = readn(sockfd, &recvbuf.len, 4); // 服务器读取
if (ret == -1)
{
ERR_EXIT("read");
}
else if (ret < 4)
{
printf("server close\n");
break;
}
n = ntohl(recvbuf.len);
ret = readn(sockfd, &recvbuf.buf, n);
if (ret == -1)
{
ERR_EXIT("read");
}
else if (ret < n)
{
printf("server close\n");
break;
}
fputs(recvbuf.buf, stdout); // 服务器返回数据输出
// 清空
memset(&recvbuf, 0, sizeof recvbuf);
memset(&sendbuf, 0, sizeof sendbuf);
}
// 5. 断开连接
close(sockfd);
return 0;
}