网络编程学习记录

 服务端首先是确定协议版本。首先定义一个结构体

WSADATA wsadata;

这个结构体是啥呢?

是Windows下得到广泛应用的、开放的、支持多种协议的网络编程接口。大家晓得了吧。

让我们看看这个结构体。

typedef struct WSAData {
  WORD           wVersion;            //低位字节指定主版本号。
  WORD           wHighVersion;        //高阶字节指定次要版本号;
  char           szDescription[WSADESCRIPTION_LEN+1];//
  char           szSystemStatus[WSASYS_STATUS_LEN+1];//
  unsigned short iMaxSockets;//
  unsigned short iMaxUdpDg;//
  char FAR       *lpVendorInfo;//
} WSADATA, *LPWSADATA;

然后调用下面这个函数启动对winsock dll的使用,那么就要判断这个函数是否要成功 

if(WSAStartup(MAKEWORD(2,2),&wsadata)!=0)
{
    cout <<"启动失败!"<<endl;
    return;
}

启动以后就要判断高低字节位有没有问题。

	//判断高低版本对不对
	if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2)
	{
		cout << "版本不对" << endl;
		return;
	}
	//1.确定协议版本
	//定义一个结构体
	WSADATA wsadata;
	//启动winsock dll,返回值不为零即为启动失败
	if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
	{
		cout << "调用winscok.dll 失败" << endl;
		return -1;
	}
	cout << "调用winscok.dll 失败\n" << endl;
	//判断高低版本对不对
	if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2)
	{
		cout << "版本不对,%d" << GetLastError() << endl;
		return -1;
	}
	cout << "版本正确"<< endl;

第二步,创建socket,分配套接字句柄

 第一个SOCK_STREAM(缺省函数):

扫描二维码关注公众号,回复: 14756335 查看本文章

 这里采用INET,tcp协议。

	//2.创建socket
	SOCKET servicesocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if (servicesocket == SOCKET_ERROR)
	{
		cout << "创建socket失败!" << endl;
		//因为创建失败,使用要清理协议版本信息
		WSACleanup();
		return -1;
	}
	cout << "创建socket成功!" << endl;

第三步,确定协议地址簇

typedef struct sockaddr_in {
  ADDRESS_FAMILY sin_family;
  USHORT         sin_port;
  IN_ADDR        sin_addr;
  CHAR           sin_zero[8];
} SOCKADDR_IN, *PSOCKADDR_IN;

SOCKADDR_IN结构为AF_INET地址系列指定传输地址和端口。


	//3.确定协议地址簇, SOCKADDR_IN结构为AF_INET地址系列指定传输地址和端口
	SOCKADDR_IN addr = { 0 };
	addr.sin_family = AF_INET;	//与socket保持一致
	addr.sin_addr.S_un.S_addr = inet_addr("192.168.31.167");//输入服务端的ip地址,要注意转换
	addr.sin_port = htonl(11223);//注意大小端,还有尽量不占用其他应用端口号,要吧端口号设置大一点

 第四步 绑定

	//4.绑定 把socket和协议地址簇绑定
	if (-1 == bind(servicesocket, (sockaddr*)&addr, sizeof addr))
	{
		cout << "绑定失败!" << endl;
		//那就要关闭socket,然后清理协议
		closesocket(servicesocket);
		WSACleanup();
		return -1;
	}
	cout << "绑定成功" << endl;

第五步 监听

	//5.监听
	//监听的数量
	if (listen(servicesocket, 10) == -1)
	{
		cout << "监听失败!" << endl;
		//那就要关闭socket,然后清理协议
		closesocket(servicesocket);
		WSACleanup();
		return -1;
	}
	cout << "监听成功" << endl;

第六步 连接

调用此成员函数以接受套接字上的连接。

virtual BOOL Accept( 
   CAsyncSocket& rConnectedSocket, 
   SOCKADDR* lpSockAddr = NULL, 
   int* lpSockAddrLen = NULL  
);
	//6.接受客户端连接
	SOCKET clientsocket = accept(servicesocket,(sockaddr*)NULL,(int*)NULL);
	if (clientsocket == SOCKET_ERROR)
	{
		cout << "客户端连接失败!" << endl;
		//那就要关闭socket,然后清理协议
		closesocket(servicesocket);
		WSACleanup();
		return -1;
	}
	cout << "连接成功" << endl;

第七步 通信

recv函数从连接的套接字或绑定的无连接套接字接收数据

int recv(
  _In_   SOCKET s,
  _Out_  char *buf,
  _In_   int len,
  _In_   int flags
);
	//7.通信
	char buffer[256];
	while (1)
	{
		int num = recv(servicesocket,buffer,255,NULL);
		buffer[num] = 0;
		cout << buffer << endl;
	}

第八步 关闭

		closesocket(servicesocket);

第九步 清理


WSACleanup();

总的服务端代码:

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

int main(void)
{
	//1.确定协议版本
	//定义一个结构体
	WSADATA wsadata;
	//启动winsock dll,返回值不为零即为启动失败
	if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
	{
		cout << "调用winscok.dll 失败" << endl;
		return -1;
	}
	cout << "调用winscok.dll 成功\n" << endl;
	//判断高低版本对不对
	if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2)
	{
		cout << "版本不对,%d" << GetLastError() << endl;
		return -1;
	}
	cout << "版本正确"<< endl;

	//2.创建socket
	SOCKET servicesocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if (servicesocket == SOCKET_ERROR)
	{
		cout << "创建socket失败!" << endl;
		//因为创建失败,使用要清理协议版本信息
		WSACleanup();
		return -1;
	}
	cout << "创建socket成功!" << endl;
	
	//3.确定协议地址簇, SOCKADDR_IN结构为AF_INET地址系列指定传输地址和端口
	SOCKADDR_IN addr = { 0 };
	addr.sin_family = AF_INET;	//与socket保持一致
	addr.sin_addr.S_un.S_addr = inet_addr("192.168.31.167");//输入服务端的ip地址,要注意转换
	addr.sin_port = htons(11223);//注意大小端,还有尽量不占用其他应用端口号,要吧端口号设置大一点
	
	//4.绑定 把socket和协议地址簇绑定
	if (-1 == bind(servicesocket, (sockaddr*)&addr, sizeof addr))
	{
		cout << "绑定失败!" << endl;
		//那就要关闭socket,然后清理协议
		closesocket(servicesocket);
		WSACleanup();
		return -1;
	}
	cout << "绑定成功" << endl;
	//5.监听
	//监听的数量
	if (listen(servicesocket, 10) == -1)
	{
		cout << "监听失败!" << endl;
		//那就要关闭socket,然后清理协议
		closesocket(servicesocket);
		WSACleanup();
		return -1;
	}
	cout << "监听成功" << endl;
	//6.接受客户端连接
	SOCKET clientsocket = accept(servicesocket,(sockaddr*)NULL,(int*)NULL);
	if (clientsocket == SOCKET_ERROR)
	{
		cout << "客户端连接失败!" << endl;
		//那就要关闭socket,然后清理协议
		closesocket(servicesocket);
		WSACleanup();
		return -1;
	}
	cout << "连接成功" << endl;
	//7.通信
	char buffer[256];
	while (1)
	{
		cout << "开始通信" << endl;
		int num = recv(servicesocket,buffer,255,NULL);
		buffer[num] = 0;
		cout << buffer << endl;
	}

	//8.断开连接
	closesocket(servicesocket);

	//9.清理版本协议信息
	WSACleanup();



	return 0;
}

接下来是客户端

客户端同理啦

只要一个连接服务端和通信有点区别

#include <iostream>

//添加头文件
#include <winsock2.h>
#include <windows.h>
#pragma comment (lib,"ws2_32.lib")

using namespace std;

int main(void)
{
	//1.确定协议版本
	WSADATA cwsadata;
	if (WSAStartup(MAKEWORD(2, 2), &cwsadata) != 0)
	{
		cout << "确定协议版本失败" << endl;
		return -1;
	}
	cout << "确定协议版本成功" << endl;
	//判断高低版本
	if (LOBYTE(cwsadata.wVersion) != 2 || HIBYTE(cwsadata.wHighVersion) != 2)
	{
		cout << "版本错误" << endl;
		return -1;
	}
	cout << "版本正确" << endl;


	//2.创建socket
	SOCKET clientsocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if (clientsocket == SOCKET_ERROR)
	{
		cout << "创建socket失败" << endl;
		closesocket(clientsocket);
		WSACleanup();
		return -1;
	}

	//3获取服务器协议簇
	SOCKADDR_IN addr = { 0 };
	addr.sin_family = AF_INET;
	addr.sin_addr.S_un.S_addr = inet_addr("192.168.31.167");
	addr.sin_port = htons(11223);

	//4连接服务器
	if (connect(clientsocket, (sockaddr*)&addr, sizeof addr) == SOCKET_ERROR)
	{
		cout << "连接失败" << GetLastError() << endl;
		closesocket(clientsocket);
		WSACleanup();
		return -1;
	}
	cout << "连接成功" << endl;

	//5通信
	char buffer[256];
	while (1)
	{
        cout <<"开始通信:";
		cin >> buffer;
		send(clientsocket, buffer, strlen(buffer), NULL);
	}


	//6关闭
	closesocket(clientsocket);

	//7清理
	WSACleanup();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/makabaka12138/article/details/128666435