栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++socket编程(五):5.1 创建tcpclient项目

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++socket编程(五):5.1 创建tcpclient项目

现在我们要开始进行客户端的编码了。
如下客户端代码:

#include "XTcp.h"
int main()
{
	XTcp client;   //client创建之后要建立连接,第一步客户端和服务器都是一样的,
	                      //区别是第二步,客户端有需要connect去连接服务器有一个三次握手的过程
	client.Connect("192.168.16.223", 8081);
	
	client.Send("clientyesyesyes", 20);

	char buffer[1024] = { 0 };

	client.Recv(buffer,sizeof(buffer));

	printf("%sn", buffer);

	return 0;
}

分析上面的代码,三次握手在客户端Connect之后,服务器accept时就已经完成。三次握手流程如下图。

通用流程代码XTcp.cpp

#include "XTcp.h"
#ifdef WIN32
#include 
#define socklen_t int
#else
#include 
#include 
#include 
#include 
#define closesocket close
#endif
#include 
#include 
#include 
#include 

using namespace std;

XTcp::XTcp()
{
#ifdef WIN32
	static bool first = true;
	if (first)
	{
		first = false;    //保证只进入一次
		WSADATA ws;
		WSAStartup(MAKEWORd(2, 2), &ws); //相当于加载了动态库,给引用增加1,这个只需要调用以此,但是需要调用在最前面
	}

#endif
}

int XTcp::CreateSocket()    //第一步创建socket
{
	sock = socket(AF_INET, SOCK_STREAM, 0);

	if (sock == -1)
	{
		printf("create socket failed!n");
	}
	return sock;
}

bool XTcp::Bind(unsigned short port)
{
	if (sock <= 0)
		CreateSocket();
	//创建
	sockaddr_in saddr;
	saddr.sin_family = AF_INET;   //协议
	saddr.sin_port = htons(port); //本地字节序转换为网络字节序
	saddr.sin_addr.s_addr = htonl(0);   //任意ip地址发过来的数据都接收

	//绑定
	//用bind绑定,绑定哪一个端口
	if (::bind(sock, (sockaddr*)&saddr, sizeof(saddr)) != 0)
	{
		printf("bind port %d failed!n", port);
		return false;
	}

	printf("bind port %d success!n", port);

	listen(sock, 10);    //这个函数已经调用,就会告诉系统,这个socket可以通过这
								//个端口来跟它进行接收连接了
								//但是,连接的信息还会用到另外一个函数。10指的是在我这次获取连接信息的时候
								//最大支持多少个连接信息
	return true;
}

int XTcp::Recv(char* buf, int bufsize)
{
	//Revc考虑一点,有时候需要接收指定大小,接收不到指定大小,就会失败
	return recv(sock, buf, bufsize, 0);
}

int XTcp::Send(const char* buf, int size)
{
	int s = 0;
	while(s!=size)   //一直发送,直到发送完毕
	{
		int len = send(sock, buf + s, size - s, 0);
		if (len <= 0)
			break;
		s += len;
	}
	return s;
}

void XTcp::Close()
{
	if (sock <= 0)
		return;
	closesocket(sock);
}

XTcp XTcp::Accept()
{
	XTcp tcp;
	sockaddr_in caddr;

	socklen_t len = sizeof(caddr);

	int client = accept(sock, (sockaddr*)&caddr, &len);//创建一个新的socket,用来与客户端单独进行通信
	if (client <= 0)
		return tcp;        //如何让外部知道我accept是成功还是失败,可以通过这个返回对象的默认socket来判断
	printf("accept client %dn", client);
	tcp.ip = inet_ntoa(caddr.sin_addr);
	tcp.port = ntohs(caddr.sin_port);       //将网络字节序转化为本地字节序
	tcp.sock = client;
	printf("client ip is %s,port is %dn", tcp.ip.c_str(), tcp.port);
	return tcp;
}

bool XTcp::Connect(const char* ip, unsigned short port)
{
	if (sock <= 0)
		CreateSocket();
	sockaddr_in saddr;
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(port);                 //本地字节序转换为网络字节序
	saddr.sin_addr.s_addr = inet_addr(ip);   //将字符串类型转化为整数类型的ip地址
	if (connect(sock, (sockaddr*)&saddr, sizeof(saddr)) != 0)
	{
		printf("connect %s:%d failed:%sn", ip, port, strerror(errno));
		return false;
	}
	printf("connect %s:%d success!n", ip, port);
	return true;

}

XTcp::~XTcp()
{

}

XTcp.h

//#pragma once
#ifndef _XTCP_H_
#define _XTPC_H_
#include 
class XTcp
{
public:
	int CreateSocket();
	bool Bind(unsigned short port);
	XTcp Accept();   //注意这个返回类型不是指针类型,我们需要在后面重新调用一个closesocket函数
	void Close();
	int Recv(char *buf,int bufsize);
	int Send(const char *buf,int sendsize);
	bool Connect(const char *ip,unsigned short port);  //注意,暂时不考虑连接超时的情况
	XTcp();
	virtual ~XTcp();
	int sock = 0;
	unsigned short port = 0;
	std::string ip;    //这些信息可以对外开放
};

#endif //_XTCH_H_

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/699559.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号