C++网络编程学习笔记(三)——客户端编程代码

C++网络编程学习笔记(三)——客户端编程代码

头文件"TcpConnect.h"
增加了Connect()函数封装

#pragma once
//因为操作繁琐,且和系统相关内容过多,对其进行封装
//初始化库,1.要么加一个函数初始化,要么在构造函数中做
#include<string>
class TcpConnect
{
public:
	int sock = 0;
	unsigned short port = 0;
	std::string ip;
public:
	TcpConnect();
	virtual ~TcpConnect();
	int CreatSocket();
	bool Bind(unsigned short port);
	//简化版本,如果想设置listen队列数量和IP地址可以重载,包含了bind和listen
	TcpConnect Accept();
	//注意返回的不是指针,是对象,所以不能在析构函数里释放,否则返回一次释放一次
	//12min重听
	//每进来一个连接,都返回该对象,判断client==0为失败
	void Close();
	//释放掉对象,否则socket会太多
	int Recv(char* buf, int bufsize);
	int Send(const char* buf, int sendsize);
	//简单封装,只隐藏个别不用的参数,记得加const
	bool Connect(const char*ip, unsigned short port);//暂时不考虑超时
	//Connect 阻塞函数
};

cpp文件"TcpConnect.cpp"
增加了Connect()函数封装实现

//头文件必须放到cpp文件,不然调用者会产生影响,只对自己内部影响
#include "TcpConnect.h"
#ifdef _WIN32
#include<windows.h>

#else
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/unistd.h>
#endif
#include<iostream>
#include<thread>
using namespace std;


TcpConnect::TcpConnect()
{
#ifdef _WIN32
	static bool first = true;
	//保证只初始化一次,多次初始化也没啥影响,因为只是引用计数加1,但增加开销
	if (first) {
		first = false;

		WSADATA ws;
		WSAStartup(MAKEWORD(2, 2), &ws);

	}
#endif
}


TcpConnect::~TcpConnect()
{
}
int TcpConnect::CreatSocket() {
	int sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock == -1) {
		cout << "creat error" << endl;
	}
	return sock;
}
bool TcpConnect::Bind(unsigned short port) {
	if (sock <= 0)CreatSocket();//简化创建
	sockaddr_in saddr;
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(port);
	saddr.sin_addr.s_addr = htonl(0);								
	if (::bind(sock, (sockaddr*)&saddr, sizeof(saddr)) != 0) {
		cout << "bind failed";
		return false;
	}
	listen(sock, 10);
	return true;
}
TcpConnect TcpConnect::Accept() {
	TcpConnect tcp;
	sockaddr_in caddr;
	int len = sizeof(caddr);
	int client = accept(sock, (sockaddr*)&caddr, (int*)len);//阻塞函数,会一直等待连接
	if (client <= 0)return tcp;
	tcp.ip = inet_ntoa(caddr.sin_addr);//inet_ntoa多线程存在问题,实际中不用
	tcp.port = ntohs(caddr.sin_port);
	tcp.sock = client;
	return tcp;
}
void TcpConnect::Close() {
	if (sock <= 0)return;
	closesocket(sock);
}
int TcpConnect::Recv(char* buf, int bufsize) {
	return recv(sock, buf, bufsize, 0);//阻塞函数
}
int TcpConnect::Send(const char* buf, int sendsize) {
	int sendedSize = 0;
	while (sendedSize!= sendsize) {
		int len = send(sock, buf + sendedSize, sendsize - sendedSize, 0);//阻塞函数
		if (len <= 0)break;
		sendedSize += len;
	}
	//循环发送,直到发送完成
	return sendedSize;
}
bool TcpConnect::Connect(const char*ip, unsigned short port) {
	if (sock <= 0)CreatSocket();
	sockaddr_in saddr;
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(port);
	saddr.sin_addr.s_addr = inet_addr(ip);
	if (connect(sock, (sockaddr*)&saddr, sizeof(saddr)) != 0) {
		cout << "connect" << ip << ",port" << port << "error." << strerror(errno);
		//后一个是打印错误信息
		return false;
	}
	return true;
}

cpp文件"main.cpp"

#include<stdlib.h>//atoi函数
#include<thread>
#include<iostream>
#include"TcpConnect.h"
using namespace std;
int main(int argc, char **argv[]) {
	TcpConnect client;
	client.Connect("127.0.0.1", 8080);
	//建立连接
	client.Send("client", 6);
	char buf[1024] = { 0 };
	client.Recv(buf, sizeof(buf));
	std::cout << buf;
	return  0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值