基于TCP协议的“消息反弹”客户端,即:本程序发送给 服务器的消息,都将被原样发回来。
client.c
#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <strings.h>
#include <stdbool.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int main(int argc, char **argv)
{
if(argc != 2)
{
printf("请指定服务端IP\n");
exit(0);
}
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
// 准备地址结构体
struct sockaddr_in addr;
bzero(&addr, sizeof(addr));
// 填入正确的服务器的IP+PORT
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(argv[1]);
addr.sin_port = htons(50021);
// 对服务器发起连接请求...
if(connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == 0)
printf("连接成功!\n");
char sendbuf[100];
char recvbuf[100];
while(1)
{
bzero(sendbuf, 100);
fgets(sendbuf, 100, stdin);
if(write(sockfd, sendbuf, strlen(sendbuf)) <= 0)
{
perror("给服务器发送数据失败");
break;
}
// 接收TCP回弹服务器发回的消息
bzero(recvbuf, 100);
if(read(sockfd, recvbuf, 100) > 0 )
printf("服务器回弹:%s", recvbuf);
}
close(sockfd);
return 0;
}
server.c
#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <strings.h>
#include <stdbool.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int sockfd; // 监听套接字
int connfd; // 连接套接字
int main(int argc, char **argv)
{
// 创建TCP套接字
sockfd = socket(AF_INET, SOCK_STREAM, 0);
// 准备本机(服务器)地址结构体
struct sockaddr_in addr;
socklen_t len = sizeof(addr);
bzero(&addr, len);
// 绑定套接字与网络地址(IP+PORT)
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY); // 自动获取本机IP
addr.sin_port = htons(50021); // 端口号PORT
if(bind(sockfd, (struct sockaddr *)&addr, len) != 0)
{
perror("绑定端口失败");
exit(0);
}
// 重新获取与套接字绑定IP和端口信息
struct sockaddr_in a = {0};
len = sizeof(a);
getsockname(sockfd, (struct sockaddr *)&a, &len);
printf("本端TCP套接字绑定的IP: %s\n", inet_ntoa(a.sin_addr));
printf("本端TCP套接字绑定的PORT: %hu\n", ntohs(a.sin_port));
// 将sockfd设置为被动监听套接字
listen(sockfd, 3);
// 准备存储对端(客户端)的地址结构体
struct sockaddr_in peeraddr;
len = sizeof(peeraddr);
bzero(&peeraddr, len);
if((connfd=accept(sockfd, (struct sockaddr *)&peeraddr, &len)) > 0)
{
printf("发现客户端[%s:%hu]连接!\n", inet_ntoa(peeraddr.sin_addr),
ntohs(peeraddr.sin_port));
}
char buf[100];
int n;
while(1)
{
bzero(buf, 100);
if((n=read(connfd, buf, 100)) == 0)
{
printf("客户端已关闭,再见!\n");
break;
}
else if(n < 0)
{
perror("读取客户端数据失败");
break;
}
printf("收到客户端消息: %s", buf);
// 将消息原样回弹给客户端
if(write(connfd, buf, strlen(buf)) < 0)
{
perror("回弹消息失败");
break;
}
}
close(connfd);
close(sockfd);
return 0;
}
效果图: