visual studio c++的网路编程——socket编程基础
1 socket 介绍
一个套接字必须包含以下信息:
- IP地址
- 端口号
- 传输层协议
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项目中;
- 服务端
#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;
}
- 客户端
#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代码写入到自己的业务代码后就会有如下错误:
解决方案: