赞
踩
首先写一个TCP.hpp的准备文件
- #ifndef TCP_HPP
- #define TCP_HPP
-
- #include <iostream>
- #include <cstring>
- extern "C"
- {
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <unistd.h>
- #include <pthread.h>
- #include <fcntl.h>
- }
-
- //设置套接字为非阻塞模式
- int setNonBlocking(int &sockfd)
- {
- //获取套接字当前状态 获取状态
- int flags = fcntl(sockfd, F_GETFL, 0);
- if (flags == -1)
- {
- return -1;
- }
- //将表示非阻塞模式的那一个标志位设置为1
- flags |= O_NONBLOCK;
- // 设置状态
- if (fcntl(sockfd, F_SETFL, flags) == -1)
- {
- return -1;
- }
- return 0;
- }
-
- class socketSend
- {
- public:
- bool running;
- socketSend(int fd) : client_fd(fd), running(true) {}
-
- void sendData() // 发送数据
- {
- char buf[1024]{};
- while (running)
- {
- memset(buf, 0, sizeof(buf));
- if (fgets(buf, sizeof(buf), stdin) == nullptr)
- continue;
- buf[strcspn(buf, "\n")] = '\0'; // 结束符替换换行符
- if (send(client_fd, buf, strlen(buf), 0) == -1)
- {
- perror("send()");
- continue;
- }
-
- if (strcmp(buf, "exit") == 0)
- {
- running = false;
- break;
- }
- }
- }
-
- private:
- int client_fd;
- };
-
- void *sendDataHelper(void *arg)//发送数据
- {
- socketSend *c1 = (socketSend *)arg;
- c1->sendData();
- return nullptr;
- }
-
- #endif

服务端代码
- #include "TCP.hpp"
- using namespace std;
-
- int main(int argc, const char *argv[])
- {
- if (argc != 2)
- {
- cout << "需要传入端口号" << endl;
- return -1;
- }
-
- // 创建套接字
- int server_fd = socket(PF_INET, SOCK_STREAM, 0);
- if (server_fd == -1)
- {
- perror("socket()");
- return -1;
- }
-
- // 设置服务端ip和端口
- sockaddr_in serverAddr;
- memset(&serverAddr, 0, sizeof(serverAddr));
- serverAddr.sin_family = AF_INET;
- serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); // 主机字节序=>网络字节序
- serverAddr.sin_port = htons(atoi(argv[1])); // 字符串=>整数=>16位网络字节序二进制值
-
- // 绑定套接字
- if (bind(server_fd, (sockaddr *)&serverAddr, sizeof(serverAddr)) == -1)
- {
- perror("bind()");
- close(server_fd);
- return -1;
- }
-
- // 设置监听
- if (listen(server_fd, 5) == -1)
- {
- perror("listen()");
- close(server_fd);
- return -1;
- }
- cout << "等待连接......" << endl;
-
- // 接收连接
- sockaddr_in clientAddr;
- memset(&clientAddr, 0, sizeof(sockaddr_in));
- socklen_t len = sizeof(clientAddr);
- int client_fd = accept(server_fd, (sockaddr *)&clientAddr, &len);
- if (client_fd == -1)
- {
- perror("accept()");
- close(client_fd);
- close(server_fd);
- return -1;
- }
- // 32位二进制网络字节序=>点分十进制字符串 0x7F000001=>“127.0.0.1”
- cout << "ip: " << inet_ntoa(clientAddr.sin_addr) << " 端口: "
- // 16位二进制网络字节序=>主机字节序 0x1234=>4660
- << ntohs(clientAddr.sin_port) << " 已连接到服务器!" << endl;
-
- setNonBlocking(client_fd); // 设置套接字为非阻塞
-
- socketSend c1(client_fd);
- pthread_t t1;
- pthread_create(&t1, nullptr, sendDataHelper, &c1);
-
- char msg[1024]{};
- while (c1.running) // 读
- {
- memset(msg, 0, sizeof(msg));
- if (recv(client_fd, msg, sizeof(msg), 0) == -1)
- {
- continue;
- }
- cout << "来自客户端:" << msg << endl;
-
- if (strcmp(msg, "exit") == 0)
- break;
- }
-
- pthread_cancel(t1);
- pthread_join(t1, nullptr);
-
- // 关闭套接字
- close(client_fd);
- close(server_fd);
- }

客户端代码
- #include "TCP.hpp"
- using namespace std;
-
- int main(int argc, char *argv[])
- {
- if (argc != 3)
- {
- cerr << "请传入服务器的ip和port!" << endl;
- return -1;
- }
-
- // 创建套接字
- int client_fd = socket(PF_INET, SOCK_STREAM, 0);
- if (client_fd < 0)
- {
- perror("sock()");
- return -1;
- }
-
- // 设置服务端信息
- sockaddr_in serverAddr;
- memset(&serverAddr, 0, sizeof(serverAddr));
- serverAddr.sin_family = AF_INET;
- serverAddr.sin_addr.s_addr = inet_addr(argv[1]); // 字符串=>32位网络字节序二进制值
- serverAddr.sin_port = htons(atoi(argv[2])); // 字符串=>整数=>16位网络字节序二进制值
-
- // 发起连接
- if (connect(client_fd, (sockaddr *)&serverAddr, sizeof(serverAddr)) == -1)
- {
- perror("connect()");
- close(client_fd);
- return -1;
- }
-
- setNonBlocking(client_fd);// 设置套接字为非阻塞
-
- socketSend s1(client_fd);
- pthread_t t1;
- pthread_create(&t1, nullptr, sendDataHelper, &s1);
-
- char msg[1024]{};
- while (s1.running)//读
- {
- memset(msg, 0, sizeof(msg));
- if (recv(client_fd, msg, sizeof(msg), 0) == -1)
- {
- continue;
- }
- cout << "来自服务端:" << msg << endl;
-
- if (strcmp(msg, "exit") == 0)
- break;
- }
-
- pthread_cancel(t1);
- pthread_join(t1, nullptr);
-
- // 关闭套接字
- close(client_fd);
- }

运行结果
任意一方输入exit,结束连接
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。