visual studio 2017 c++的网路编程——winsock基础

1 socket 介绍

一个套接字必须包含以下信息:

  1. IP地址
  2. 端口号
  3. 传输层协议

2 winsock编程基础

  • winsock目前有两个版本:winsock1和winsock2.
  • winsock2可以看成是winsock1的增强版;winsock2包含了winsock1的所有API和套接字。同时增加了很多新的功能,更重要是的是winsock1是为tcp/ip编写的,而winsock2还允许其他协议族;
  • 换句话说winsock2是独立于具体网络协议的API.另外winsock2基本上兼容winsock1.

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

#include<winsock2.h>
#include<windows.h>
#pragma comment (lib,"Ws2_32.lib");

3 代码

先启动服务端程序,再启动客户端程序;下面两个代码是属于不同的vs项目中;

  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;
}
  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 sockClient = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
	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);

	if (connect(sockClient, (SOCKADDR*)&addrServer, sizeof(addrServer))== SOCKET_ERROR)
	{
		cout << "connect error" << endl;
	}
	//connect(sockClient, (SOCKADDR*)&addrServer, sizeof(addrServer));
	string str = "windows socket test";
	/*while (1)
	{*/
		int len = send(sockClient, str.c_str(), str.length(), 0);
		if (len < str.length())
		{
			cout << "data send uncompleted" << endl;
			str = str.substr(len + 1, str.length());
			len = send(sockClient, str.c_str(), str.length(), 0);
			cout << "send data uncomplete,send remaining data :" << str.c_str() << " ,length = " << str.length() << endl;
		}
		Sleep(1);

	//}
		//接受服务器消息
		char buf[1024];
		 len = recv(sockClient, buf, 1024, NULL);
		cout << "服务端:" << buf << endl;
	closesocket(sockClient);
	WSACleanup();
	while (true)
	{

	}
	return 0;

}

程序运行结果:
在这里插入图片描述
下面是加了服务端给客户端发送数据的代码的结果,注意:以上代码运行出来的结果如下:
在这里插入图片描述

4 std::bind 和Socket中的bind函数起冲突的解决方案

问题描述:
在将winsock代码写入到自己的业务代码后就会有如下错误:
在这里插入图片描述
解决方案:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值