Windows_TCP_客户端服务端

服务端:socket->bind->listen->accept->recv/send->close
客户端:socket-connect->send/recv->close

Socket 函数
{
socket()
bind() //服务端使用
listen() //服务端使用
accept() //服务端使用
connect() //客户端使用
send()
recv()
select()
closeSocket()

}

ip地址转换
{
低分ip地址(192.168.123.12/主要是为了好记忆,计算机不认识) 需转换成一个 32位无符号长整数(这个才是真的ip地址);
转换函数:
s_addr = inet_addr(“192.168.123.1”);

}

字节转化
{
@大端字节(big-endian)

@小段字节(little-endian)

@主机字节(host-byte)
{
	不同的主机(windows(小端)/linux)用的主机字节不同,要么是大端 要么是小端
}


*网络字节(network-byte)*
{
	网络上传输的数据是按大端字节顺序传输的,那么在windows上编程的话那么就需要转换字节序了
}

@转换函数{
	htons(主机(host)转换(to)成网络(net)的短整型(short));
	htonl(主机(host)转换(to)成网络(net)的长整型(long));
	
	ntohs(); //网络转本机short类型
	ntohl(); //网络转本机long类型
	
}

}

TCP Socket编程
{
@流式套接字
tcp/ip
SOCK_STREAM

@服务端程序:socket->bind->listen->accept->recv/send->close

@客户端:socket-connect->send/recv->close

##TCPServer实现
@头文件
#pragma comment(lib,“ws2_32.lib”);
#include <WinSock2.h>

}
代码:
服务端

#include<iostream>
#include<stdlib.h>
#include<WinSock2.h>
using namespace std;
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable : 4996)

int main()
{
	WSADATA wsaData;
	int Ret = 0;
	//1.MAKEWORD(2,2): 2.2版本的WinSock;初始化widnows套接字
	Ret = WSAStartup(MAKEWORD(2,2), &wsaData);
	if (Ret != 0)
	{
		cout << "WSAStartup init erro:" <<Ret<< endl;
		return 0;
	}

	//2.申请服务端套接字
	SOCKET ListingSocket;
	ListingSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); //SOCK_STREAM tcp属于流形式的套接字
	if (ListingSocket == INVALID_SOCKET)
	{
		cout << "socket is  erro:"  << WSAGetLastError() <<endl;
		WSACleanup();
		return 0;
	}

	//3.bind
	SOCKADDR_IN ServerAddr;
	ServerAddr.sin_family = AF_INET; //协议:Internet协议
	int port = 5150;
	ServerAddr.sin_port = htons(port); //端口(有6w多个端口,但是不能重复,选大一点的端口比较保险);同时要转成(htons)网络使用的字节序
	ServerAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //设置任何客户端的ip都能连接;不限制客户端的ip
	if (SOCKET_ERROR == (bind(ListingSocket, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr))))
	{
		cout << "socket bind  erro:" << WSAGetLastError() << endl;
		closesocket(ListingSocket); //关闭套接字
		WSACleanup();
		return 0;
	}

	//4.开始监听
	if (SOCKET_ERROR == (listen(ListingSocket, 5)))//允许5个连接(队列大小是5) 不要设置太大
	{
		cout << "socket listen  erro:" << WSAGetLastError() << endl;
		closesocket(ListingSocket); //关闭套接字
		WSACleanup();
		return 0;
	}

	cout << "we are wating for connecting on port:" << port << endl;
	cout << "Listen(正在监听)" << endl;

	//5有客户端连接我们就接受客户端连接
	SOCKADDR_IN ClientAddr; //客户端地址
	int ClinetAddrLen = sizeof(SOCKADDR); //客户端地址长度
	SOCKET NewConnection;	//服务端接受成功会得到一个客户端的套接字,每一个新的客户端的套接字代表一个新的连接
	NewConnection = accept(ListingSocket,(SOCKADDR*)&ClientAddr, &ClinetAddrLen);
	if (NewConnection == INVALID_SOCKET)
	{
		cout << "socket accept  erro:" << WSAGetLastError() << endl;
		closesocket(ListingSocket); //关闭套接字
		WSACleanup();
		return 0;
	}

	cout << "we successfully got a connection form ip: " << inet_ntoa(ClientAddr.sin_addr) << "; port:" << ntohs(ClientAddr.sin_port) <<endl;

	//6.关闭套接字
	closesocket(ListingSocket); //关闭套接字,这个例子只接受一个客户端连接

	cout << "We are winting for receive data" << endl;

	//接受数据
	char dataBuffer[1024]; //客户端发来的东西放这里面
	if (SOCKET_ERROR == (Ret = recv(NewConnection, dataBuffer, sizeof(dataBuffer), 0)))
	{
		cout << "socket recv  erro:" << WSAGetLastError() << endl;
		closesocket(NewConnection); //关闭客户端的套接字
		WSACleanup();
		return 0;
	}
	cout << "we successfully recv :"<< Ret << "bytes"<<endl;
	//收到的buf都是字符串 我们要把buf 的最后一个字节加上"\0";
	dataBuffer[Ret] = '\0';
	cout << "recv buf is" << dataBuffer <<endl;

	//关闭客户端的套接字做清理
	closesocket(NewConnection); //关闭客户端的套接字
	WSACleanup();
	system("pause");
	return 0;
}

客户端

#include<iostream>
#include<stdlib.h>
#include<WinSock2.h>
using namespace std;
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable : 4996)

int main(int argc, char** argv)
{
	if (argc <= 1)
	{
		//TCPClient 127.0.0.1
		cout << "usage : TCPClinet <Server IP address>." << endl;
		system("pause");
		return 0;
	}
	WSADATA wsaData;
	int Ret = 0;
	//1.MAKEWORD(2,2): 2.2版本的WinSock;初始化widnows套接字
	Ret = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (Ret != 0)
	{
		cout << "WSAStartup init erro:" << Ret << endl;
		return 0;
	}

	//2.申请客户端套接字
	SOCKET s;
	s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //SOCK_STREAM tcp属于流形式的套接字
	if (s == INVALID_SOCKET)
	{
		cout << "socket is  erro:" << WSAGetLastError() << endl;
		WSACleanup();
		return 0;
	}

	//3.连接服务器
	SOCKADDR_IN ServerAddr;
	ServerAddr.sin_family = AF_INET; //协议:Internet协议
	int port = 5150;
	ServerAddr.sin_port = htons(port); //端口(有6w多个端口,但是不能重复,选大一点的端口比较保险);同时要转成(htons)网络使用的字节序
	//ServerAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //设置服务端的地址(这里就在本机测试)
	ServerAddr.sin_addr.S_un.S_addr = inet_addr(argv[1]); //设置服务端的地址(使用命令行来输出)

	cout << "we are try to connet :" << inet_ntoa(ServerAddr.sin_addr)<<";port:"<<htons(ServerAddr.sin_port)<<endl;
	//4. 连接服务端
	if (SOCKET_ERROR == (connect(s, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr))))
	{
		cout << "socket connect  erro:" << WSAGetLastError() << endl;
		closesocket(s); //关闭套接字
		WSACleanup();
		return 0;
	}
	cout << "socket connnetion succeessed, we will send a message to server" << endl;
	//5发送数据
	if ((Ret = send(s, "fuck?", 5, 0)) == SOCKET_ERROR )
	{
		cout << "socket send  erro:" << WSAGetLastError() << endl;
		closesocket(s); //关闭套接字
		WSACleanup();
		return 0;
	}
	
	cout << "we are successed send " << Ret << "bytes to server" << endl;
	//6 关闭套接字
	closesocket(s); //关闭套接字
	WSACleanup();

	system("pause");
	return 0;
}

验证图:在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值