C++Socket

Server

#include<Winsock2.h>
#include<stdio.h>
#include <iostream>
#include <string>
using namespace std;
int main()
{
	//**********************************************************
	//第一步:加载socket库函数
	//**********************************************************

	//定义一个WORD的变量
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	//低字节主版本号 高字节副版本号 如下是版本2.1
	//(WORD)(1<<8|2)
	wVersionRequested = MAKEWORD(2,1);
	
	//WSAStartup应该与WSACleanup成对使用,WSAStartup的功能是初始化Winsock DLL,
	//WSACleanup是来解除与Socket库的绑定并且释放Socket库所占用的系统资源
	//WSAStartup函数的第一个参数是加载WinSock库的版本,WSAStartup函数的第二个参数中设置使用的WinSock库的版本,
	//当正确初始化时,WSAStartup会返回0。但我在WSAStartup函数的第一个参数中胡乱设置了一个版本号,WSAStartup仍然会返回0。
	//最后经测试发现,如果在WSAStartup函数第一个参数中设置的版本号不存在,那么会自动使用WinSock库中最高版本2.2
	err = WSAStartup(wVersionRequested, &wsaData);

	if (err != 0)
	{
		cout << "*******Fail to load Socket!*******" << endl;
		return 0;
	}
	else
	{
		cout << "*******Success to load Socket!*******" << endl;
	}

	if (LOBYTE(wsaData.wVersion) != 2 ||HIBYTE(wsaData.wVersion) != 1) 
	{
		cout << "*******版本不是2.1版本*******" << endl;
		WSACleanup();
		return 0;
	}

	//**********************************************************
	//第二步创建套接字
	//**********************************************************
	//af:		一个地址描述。目前仅支持AF_INET格式,也就是说ARPA Internet地址格式。
	//type:		指定socket类型。新套接口的类型描述类型,如TCP(SOCK_STREAM)和UDP(SOCK_DGRAM)。	
	//			常用的socket类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等。
	//protocol:顾名思义,就是指定协议。套接口所用的协议。如调用者不想指定,可用0。常用的协议有,IPPROTO_TCP、IPPROTO_UDP、IPPROTO_STCP、IPPROTO_TIPC等,它们分别对应TCP传输协
	//			议、UDP传输协议、STCP传输协议、TIPC传输协议。
	SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);
	
	
	//**********************************************************
	//第三步:绑定套接字
	//**********************************************************
	//获取地址结构
	SOCKADDR_IN addrSrv;
	//typedef struct sockaddr_in {
	//#if(_WIN32_WINNT < 0x0600)
	//	short   sin_family;
	//#else //(_WIN32_WINNT < 0x0600)
	//	ADDRESS_FAMILY sin_family;
	//#endif //(_WIN32_WINNT < 0x0600)
	//	USHORT sin_port;
	//	IN_ADDR sin_addr;
	//	CHAR sin_zero[8];
	//} SOCKADDR_IN, *PSOCKADDR_IN;
	//sa_family是地址家族,一般都是“AF_xxx”的形式。通常大多用的是都是AF_INET, 代表TCP / IP协议族。
	//sa_data是14字节协议地址。

	addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	//将IP地址指定为INADDR_ANY,允许套接字向任何分配给本地机器的IP地址发送或接收数据
	//监听所有发送请求的地址
	//htonl()将主机的无符号长整形数转换成网络字节顺序。
	//host to network, l 的意思是返回类型是long

	addrSrv.sin_family = AF_INET;
	//sin_family 表示地址族,对于IP地址,sin_family成员将一直是AF_INET
	
	addrSrv.sin_port = htons(6000);
	//htons()就是将一个数的高低位互换 高八位与低八位呼唤位置
	//htons()将主机的无符号短整形数转换成网络字节顺序

	bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
	//int bind(int sockfd, const struct sockaddr * my_addr, socklen_t addrlen);
	//返回:成功返回0,失败返回 - 1.
	//参数列表中,sockfd 表示已经建立的socket编号(描述符);
	//my_addr 是一个指向sockaddr结构体类型的指针;
	//参数addrlen表示my_addr结构的长度,可以用sizeof函数获得。
	
	listen(sockSrv, 5);
	//参数一:用于标识一个已捆绑未连接套接口的描述字
	//参数二:等待连接队列的最大长度
	//监听客户端

	//定义从客户端接受的地址信息
	SOCKADDR_IN addrClient;
	int len = sizeof(SOCKADDR);

	cout << "**********等待客户端的连接**********" << endl;
	SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len);
	//参数一:套接字描述符,该套接口在listen()后监听连接
	//指针,指向一缓冲区,其中接收为通讯层所知的连接实体的地址。Addr参数的实际格式由套接口创建时所产生的地址族确定。
	//addrlen:(可选)指针,输入参数,配合addr一起使用,指向存有addr地址长度的整型数
	//(可选)指针,指向一缓冲区,其中接收为通讯层所知的连接实体的地址。Addr参数的实际格式由套接口创建时所产生的地址族确定。
	//addrlen:(可选)指针,输入参数,配合addr一起使用,指向存有addr地址长度的整型数
	while (1)
	{
		string sendBuf;
			//sendBuf= "欢迎IP:"+inet_ntoa(addrClient.sin_addr) ;
			//sprintf(sendBuf, "welcome %s to 济南", inet_ntoa(addrClient.sin_addr));
		cout << "来自服务器的信息:";
		cin >> sendBuf;
		send(sockConn, sendBuf.c_str(), strlen(sendBuf.c_str()) + 1, 0);

		char recvBuf[256];
		recv(sockConn, recvBuf, 256, 0);
		cout << "来自客户端的信息:" << recvBuf << endl;;
	}
	closesocket(sockConn);
	WSACleanup();

	return 0;

}

Client

#include<Winsock2.h>
#include <iostream>
#include <string>
using namespace std;
#pragma comment(lib,"ws2_32.lib")
int main()
{
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	wVersionRequested = MAKEWORD(1, 1);

	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0) {
		return 0;
	}

	if (LOBYTE(wsaData.wVersion) != 1 ||
		HIBYTE(wsaData.wVersion) != 1) {
		WSACleanup();
		return 0;
	}

	//**********************************************************
	//第一步,创建套接字
	SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);

	//定义套接字地址
	SOCKADDR_IN addrSrv;

	//获取服务器IP地址,inet_addr()将IP地址转为点分十进制的格式
	addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");  

	//sin_family 表示地址族,对于IP地址,sin_family成员将一直是AF_INET
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(6000);


	if (connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)) != 0)
	{
		cout << "与服务器连接失败" << endl;;
		return 0;
	}
	else
	{
		cout << "**********连接服务器成功**********" << endl;
		while (1)
		{
			string  sendBuf;
			cout << "来自客户端的信息:";
			cin >> sendBuf;
			send(sockClient, sendBuf.c_str(), strlen(sendBuf.c_str()) + 1, 0); 
			
			char recvBuf[256];
			recv(sockClient, recvBuf, 256, 0);
			cout << "来自服务器的信息:" << recvBuf << endl;

			
		}
	}
	
	//关闭套接字
	closesocket(sockClient);
	//清除套接字资源
	WSACleanup();
	return 0;

}

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值