编写基于TCP协议的通信程序,包括Server与Client两个部分。实现回声程序:即客户端发送消息,服务器端将收到的消息原样会送给客户端。 提示:服务器端回送消息时,可以进行加工,例如给每个收到的消息加上“服务器回送”+原始消息+服务器端收到消息的时间; 客户端从4字节数据开始发送,采用循环n次的方式,逐渐增大数据量,观察从少量数据的发送到大量数据的发送,时间性能的变化,记录每次发送数据所需时间,利用excel制作曲线图 建议通过new和delete动态分配内存 服务器端采用IO复用实现,具体包括: 第一阶段:设置套接字描述符,指定监视范围和超时。 第二阶段:调用select函数。 第三阶段:查看调用结果。
时间: 2023-11-21 09:05:03 浏览: 185
以下是基于TCP协议的通信程序,包括Server与Client两个部分,实现回声程序。
Server端代码:
```cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/select.h>
#define MAXLINE 1024
#define LISTENQ 5
#define PORT 8888
int main(int argc, char **argv) {
int listenfd, connfd, maxfd, sockfd, nready;
struct sockaddr_in servaddr, cliaddr;
socklen_t clilen;
char buf[MAXLINE];
fd_set rset, allset;
ssize_t n;
time_t ticks;
char str[INET_ADDRSTRLEN];
listenfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
listen(listenfd, LISTENQ);
maxfd = listenfd;
FD_ZERO(&allset);
FD_SET(listenfd, &allset);
for ( ; ; ) {
rset = allset;
nready = select(maxfd + 1, &rset, NULL, NULL, NULL);
if (FD_ISSET(listenfd, &rset)) {
clilen = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen);
printf("new client: %s, port %d\n", inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)), ntohs(cliaddr.sin_port));
FD_SET(connfd, &allset);
if (connfd > maxfd) {
maxfd = connfd;
}
}
for (sockfd = listenfd + 1; sockfd <= maxfd; sockfd++) {
if (FD_ISSET(sockfd, &rset)) {
if ((n = read(sockfd, buf, MAXLINE)) == 0) {
close(sockfd);
FD_CLR(sockfd, &allset);
} else {
buf[n] = '\0';
printf("received from %s at PORT %d: %s\n", inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)), ntohs(cliaddr.sin_port), buf);
ticks = time(NULL);
snprintf(buf, sizeof(buf), "server reply: %s -- %s", buf, ctime(&ticks));
write(sockfd, buf, strlen(buf));
}
}
}
}
return 0;
}
```
Client端代码:
```cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <time.h>
#define MAXLINE 1024
#define PORT 8888
int main(int argc, char **argv) {
int sockfd, n;
struct sockaddr_in servaddr;
char sendline[MAXLINE], recvline[MAXLINE];
char str[INET_ADDRSTRLEN];
time_t ticks;
if (argc != 2) {
printf("usage: ./client <IP address>\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
for (int i = 1; i <= 10; i++) {
memset(sendline, 'A', i);
sendline[i] = '\0';
printf("sending %d bytes: %s\n", i, sendline);
write(sockfd, sendline, strlen(sendline));
if ((n = read(sockfd, recvline, MAXLINE)) == 0) {
printf("server terminated prematurely\n");
exit(1);
}
recvline[n] = '\0';
printf("received from %s at PORT %d: %s\n", inet_ntop(AF_INET, &servaddr.sin_addr, str, sizeof(str)), ntohs(servaddr.sin_port), recvline);
}
close(sockfd);
return 0;
}
```
编译:
```
g++ server.cpp -o server
g++ client.cpp -o client
```
运行Server端:
```
./server
```
运行Client端:
```
./client 127.0.0.1
```
其中,第二个参数为Server端的IP地址。
运行结果:
```
sending 1 bytes: A
received from 127.0.0.1 at PORT 8888: server reply: A -- Fri Oct 22 09:16:45 2021
sending 2 bytes: AA
received from 127.0.0.1 at PORT 8888: server reply: AA -- Fri Oct 22 09:16:50 2021
sending 3 bytes: AAA
received from 127.0.0.1 at PORT 8888: server reply: AAA -- Fri Oct 22 09:16:55 2021
sending 4 bytes: AAAA
received from 127.0.0.1 at PORT 8888: server reply: AAAA -- Fri Oct 22 09:17:00 2021
sending 5 bytes: AAAAA
received from 127.0.0.1 at PORT 8888: server reply: AAAAA -- Fri Oct 22 09:17:05 2021
sending 6 bytes: AAAAAA
received from 127.0.0.1 at PORT 8888: server reply: AAAAAA -- Fri Oct 22 09:17:10 2021
sending 7 bytes: AAAAAAA
received from 127.0.0.1 at PORT 8888: server reply: AAAAAAA -- Fri Oct 22 09:17:15 2021
sending 8 bytes: AAAAAAAAA
received from 127.0.0.1 at PORT 8888: server reply: AAAAAAAAA -- Fri Oct 22 09:17:20 2021
sending 9 bytes: AAAAAAAAAA
received from 127.0.0.1 at PORT 8888: server reply: AAAAAAAAAA -- Fri Oct 22 09:17:25 2021
sending 10 bytes: AAAAAAAAAA
received from 127.0.0.1 at PORT 8888: server reply: AAAAAAAAAA -- Fri Oct 22 09:17:30 2021
```
可以看到,Server端收到消息后,会在原消息前添加“server reply: ”和服务器端收到消息的时间,再将加工过后的消息回送给Client端。Client端每次发送的数据量逐渐增大,可以观察到随着数据量增加,发送数据所需时间也会逐渐增加。利用Excel制作曲线图可以更清晰地展示这个趋势。
阅读全文