大前端

前端学习之家-大前端

c++网络技术支撑

 服务器端代码:

  1. #define _WINSOCK_DEPRECATED_NO_WARNINGS
    #include<WinSock2.h>
    #include<Windows.h>
    #include<iostream>
    using namespace std;
    #pragma comment(lib,"ws2_32")
    
    int main()
    {
    	WSADATA wsaDate = {};
    	WSAStartup(MAKEWORD(2, 2), &wsaDate);
    	SOCKET sockServer = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    	//SOCKET sockServer = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
    	sockaddr_in addrServer = {};
    	addrServer.sin_family = PF_INET;
    	addrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//绑定本机地址
    	addrServer.sin_port = htons(10000);
    	//绑定服务器端口号和IP地址
    	int bind_server = bind(sockServer, (SOCKADDR*)&addrServer, sizeof(addrServer));
    	if (bind_server != 0)
    	{
    		cout << "bind error" << endl;
    	}
    	listen(sockServer, 2);
    	//客户端
    	SOCKET sockClient = {};
    	SOCKADDR addrClient = {};
    	int nSzie = sizeof(addrClient);
    	sockClient = accept(sockServer, &addrClient, &nSzie);
    	if (sockClient == INVALID_SOCKET)
    	{
    		cout << "accept error" << endl;
    	}
    	printf("客户端已经连接\n");
    
    	//1.向客户端发送信息
    	string str = "hello client";
    	send(sockClient, str.c_str(), str.length(), NULL);
    	/*while (1)
    	{*/
    	//2.接受客户端信息
    	char buf[1024];
    	int len = recv(sockClient, buf, 1024, 0);
    	if (len == 0)
    	{
    		cout << "connection has closed" << endl;
    		//break;
    	}
    	else if (len == SOCKET_ERROR)
    	{
    		cout << "recv error" << WSAGetLastError() << endl;
    		//break;
    	}
    	else
    	{
    		char* outbuf = new char[len + 1];
    		memcpy(outbuf, buf, len);
    		outbuf[len] = 0;
    		cout << "recv data:" << outbuf << endl;
    		delete outbuf;
    	}
    	//}
    	closesocket(sockServer);
    	closesocket(sockClient);
    	WSACleanup();
    	return 0;
    }

WSADATA:这个结构体被用来存储被WSAStartup函数调用后返回的Winsock.dll执行的数据功能是:存放windows socket初始化信息。使用形式:WSADATA IpWSAData。IpWSAData:WSADATA结构体变量的地址值。

要使用winsock2,需要用的头文件是winsock2.h.需要用到的库是Ws2_32.lib;这个在visual studio中直接包含,不需要下载,直接包含winsock2.h头文件既可;在代码中添加入下面两句代码即可

#include<WinSock2.h>
#include<Windows.h>
#include<iostream>
using namespace std;
#pragma comment(lib,"ws2_32")

还有一段防止报错的宏定义

#define _WINSOCK_DEPRECATED_NO_WARNINGS

WSAStartup();主要就是进行相应的socket库绑定。
函数原型:int WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData );
使用Socket的程序在使用Socket之前必须调用WSAStartup函数。以后应用程序就可以调用所请求的Socket库中的其它Socket函数了,然后绑定找到的Socket库到该应用程序中。该函数执行成功后返回0。

WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData)。即为WSAStartup(Winsock版本号,WSADATA变量地址名)。

建立socket:SOCKET 变量名=socket(PF_INET, SOCK_STREAM,0) 或socket(AF_INET, SOCK_STREAM,0)。

1、参数domain指明通信域,如PF_UNIX(unix域),PF_INET(IPv4),PF_INET6(IPv6)等。

2、type 指明通信类型,最常用的如SOCK_STREAM(面向连接可靠方式,  比如TCP)、SOCK_DGRAM(非面向连接的非可靠方式,比如UDP。

3、参数protocol指定需要使用的协议。虽然可以对同一个协议  家族(protocol family)(或者说通信域(domain))指定不同的协议  参数,TCP参数可指定为IPPROTO_TCP,对于  UDP可以用IPPROTO_UDP。你不必显式制定这个参数,使用0则根据前两个参数使用默认的协议。

4、sockaddr_in即为客户端绑定地址信息结构体。头文件中定义为:

typedef struct sockaddr_in { //程序员应使用sockaddr_in来表示地址,sockaddr_in区分了地址和端口
    short            sin_family;     // 2 bytes e.g. AF_INET, PF_INET6
    //sockaddr用其余14个字节来表示sa_data, sockaddr_in把14个字节拆分成sin_port, sin_addr和sin_zero
    unsigned short   sin_port;       // 2 bytes e.g. htons(3490), 端口号
    IN_ADDR sin_addr;            //struct in_addr   sin_addr;       // 4 bytes see struct in_addr, below, IP 地址
    char             sin_zero[8];    // 8 bytes zero this if you want to, sin_zero用来填充字节使sockaddr_in和sockaddr保持一样大小
}SOCKADDR_IN;

AF 表示ADDRESS FAMILY 地址族

PF 表示PROTOCOL FAMILY 协议族

在windows系统中,这两个宏定义是一样的,所以使用哪个都没有关系。即定义地址类型为IP。

如代码中的形式比较固定作为绑定主机号和服务器端口号。

sockaddr_in addrServer = {};
	addrServer.sin_family = PF_INET;
	addrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//绑定本机地址
	addrServer.sin_port = htons(10000);
	//绑定服务器端口号和IP地址

绑定函数:

if (bind(s_server, (SOCKADDR *)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {undefined

cout << "套接字绑定失败!" << endl;

listen(s_server, SOMAXCONN)。监听函数,参数为套现字变量名,连接设置长度。

 WSACleanup();//释放DLL资源

初始化客户端套现字,和初始化客户端地址。

SOCKET sockClient = {};
SOCKADDR addrClient = {};

nt accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);accept函数接受显示为客户端连接成功:

int nSzie = sizeof(addrClient);
sockClient = accept(sockServer, &addrClient, &nSzie);

主机向客户端发送信息用到send()函数,send(发送socket 变量名,发送字符串,字符串长度,null或者0)

string str = "hello client";
send(sockClient, str.c_str(), str.length(), NULL);

以及主机接收客户端的信息用到recv()函数,recv(接收端socket变量名,接收缓存区,可接收字符串最大长度,null或0)

char buf[1024];
int len = recv(sockClient, buf, 1024, 0);

连接完成释放连接:

closesocket(sockServer);
closesocket(sockClient);
WSACleanup();
return 0;

发表评论:

Copyright Your WebSite.Some Rights Reserved.