欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 社会 > 【计算机网络】TCP网络程序

【计算机网络】TCP网络程序

2024/11/14 15:47:26 来源:https://blog.csdn.net/m0_73551869/article/details/143722690  浏览:    关键词:【计算机网络】TCP网络程序

一、服务端

1.tcpServer.hpp

#pragma once
#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <signal.h>
#include <pthread.h>enum
{USAGE_ERR = 1,SOCKET_ERR,BIND_ERR,LISTEN_ERR
};static const uint16_t gport = 8080;
static const int gbacklog = 5;
class TcpServer;class ThreadData
{
public:ThreadData(TcpServer *self, int sock): _self(self), _sock(sock){}public:TcpServer *_self;int _sock;
};class TcpServer
{
public:// 构造函数TcpServer(const uint16_t &port = gport): _listensock(-1), _port(port){}// 析构函数~TcpServer() {}// 初始化服务器void initServer()// 启动服务器void start()private:int _listensock; // 不是用来进行数据通信的,他是用来监听链接到来,获取新链接的!uint16_t _port;  // 端口号
};

(1)initServer()

void initServer()
{// 1.创建socket文件套接字对象_listensock = socket(AF_INET, SOCK_STREAM, 0);if (_listensock < 0){logMessage(FATAL, "create socket error");exit(SOCKET_ERR);}logMessage(NORMAL, "create socket success:%d", _listensock); // ? 后面可能会加东西// 2.bind绑定自己的网络信息struct sockaddr_in local;memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_port = htons(_port);local.sin_addr.s_addr = INADDR_ANY;if (bind(_listensock, (struct sockaddr *)&local, sizeof(local)) < 0){logMessage(FATAL, "bind socket error");exit(BIND_ERR);}logMessage(NORMAL, "bind socket success");// 3.设置socket 为监听状态if (listen(_listensock, gbacklog) < 0) // listen第二个参数以后在讲{logMessage(FATAL, "listen socket error");exit(LISTEN_ERR);}logMessage(NORMAL, "listen socket success");
}

(2)start()

void start()
{for (;;){// 4.server 获取新链接// sock 才是和client进行通信的fdstruct sockaddr_in peer;socklen_t len = sizeof(peer);int sock = accept(_listensock, (struct sockaddr *)&peer, &len);if (sock < 0){logMessage(ERROR, "accept error, next");continue;}logMessage(NORMAL, "accept a new link success, get new sock:%d", sock);// 5.这里就是一个sock,未来通信我们就用这个sock,面向字节流的,后续全部都是文件操作!serviceIO(sock);close(sock); // 对一个已经使用完毕的sock,我们要关闭这个sock,要不然会导致,文件描述符泄露}
}

2.tcpServer.cpp

#include "tcpServer.hpp"
#include <memory>using namespace std;// 使用手册
static void Usage(string proc)
{cout << "\nUsage:\n\t" << proc << " local_port\n\n";
}// ./tcpServer local_port
int main(int argc, char *argv[])
{if(argc != 2){Usage(argv[0]);exit(USAGE_ERR);}uint16_t port = atoi(argv[1]);// tcp服务器的调用逻辑unique_ptr<TcpServer> tsvr(new TcpServer(port));tsvr->initServer();tsvr->start();return 0;
}

二、客户端

1.tcpClient.hpp

#pragma once#include <iostream>
#include <string>
#include <cstring>
#include <sys/types.h>         
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>#define NUM 1024class TcpClient
{
public:// 构造函数TcpClient(const std::string &serverip, const uint16_t &serverport):_sock(-1), _serverip(serverip), _serverport(serverport){}// 析构函数~TcpClient(){if(_sock >= 0)close(_sock);}// 初始化客户端void initClient()// 启动客户端void start()private:int _sock;std::string _serverip;uint16_t _serverport;
};

(1)initClient()

void initClient()
{// 1.创建socket_sock = socket(AF_INET, SOCK_STREAM, 0);if (_sock < 0){std::cerr << "socket create error" << std::endl;exit(2);}// 2.tcp的客户端要不要bind?要的! 但是要不要显示的bind?不要!尤其这里client port要让OS自己随机指定!// 3.要不要listen?不要!// 4.要不要accept?不要!
}

(2)start()

void start()
{// 5.要发起连接!struct sockaddr_in server;memset(&server, 0, sizeof(server));server.sin_family = AF_INET;server.sin_port = htons(_serverport);server.sin_addr.s_addr = inet_addr(_serverip.c_str());if (connect(_sock, (struct sockaddr *)&server, sizeof(server)) != 0){std::cerr << "socket connet error" << std::endl;}else{// 成功连接std::string msg;while (true){std::cout << "Enter# ";std::getline(std::cin, msg);write(_sock, msg.c_str(), msg.size());char buffer[NUM];int n = read(_sock, buffer, sizeof(buffer) - 1);if (n > 0){// 目前我们可以吧读到的数据当成字符串buffer[n] = 0;std::cout << "Server回显# " << buffer << std::endl;}else{break;}}}
}

2.tcpClient.cpp

#include "tcpClient.hpp"
#include <memory>// 使用手册
static void Usage(std::string proc)
{std::cout << "\nUsage:\n\t" << proc << " serverip serverport\n\n";
}// ./tcpclient serverip serverport
int main(int argc, char *argv[])
{if(argc != 3){Usage(argv[0]);exit(1);}std::string serverip = argv[1];uint16_t serverport = atoi(argv[2]);std::unique_ptr<TcpClient> tcli(new TcpClient(serverip, serverport));tcli->initClient();tcli->start();return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com