1. Socket基础API
引入两个头文件。
#include<Windows.h>
#include<WinSock2.h>
但是发现会报错。
Windows.h一些定义较早,在WinSock2.h中也有定义,为了解决冲突,有两种方法。
- #define WIN32_LEAN_AND_MEAN
- #include<WinSock2.h>放在Windows.h前面
报错
解法方法:
- 链接器里面加入 ws2_32.lib
- 此方法只适用win系统 引入 #pragma comment(lib,"ws2_32.lib")
sockaddr_int 结构体
存放socket信息。
typedef struct sockaddr_in {
#if(_WIN32_WINNT < 0x0600)
short sin_family;
#else //(_WIN32_WINNT < 0x0600)
ADDRESS_FAMILY sin_family;//AF_INET ip协议
#endif //(_WIN32_WINNT < 0x0600)
USHORT sin_port; //port
IN_ADDR sin_addr;//IP address, unsigned long
CHAR sin_zero[8];// align
}
2. 简易Tcp服务端客户端 1.0
只能一次收发数据
Server:
#include <iostream>
#define WIN32_LEAN_AND_MEAN
#include<Windows.h>
#include<WinSock2.h>
using namespace std;
/* 只能在win条件下
//调用 win 静态链接库
#pragma comment(lib,"ws2_32.lib")
*/
int main()
{
//版本号
WORD ver = MAKEWORD(2, 2);
WSADATA dat;
WSAStartup(ver, &dat);
//1. 建立一个Socket
//ipv4 字节流 tcp类型
SOCKET _sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//2. bind 绑定用于接受客户端连接的网路端口
// 创建一个sockaddr 结构体 存放socket信息
sockaddr_in _sin = {};
_sin.sin_family = AF_INET;//指定ipv4协议 ipv6 AF_INET6
_sin.sin_port = htons(4567); // host to net unsigned short
//sin_addr ... 是一个联合体 不是一个对象套对象
//INADDR_ANY 不限定ip地址 任何一个都可以
_sin.sin_addr.S_un.S_addr = INADDR_ANY;// inet_addr("127.0.0.1");
if (SOCKET_ERROR == bind(_sock, (sockaddr*)&_sin, sizeof _sin)) {
cout << "绑定端口失败" << endl;
}
else {
cout << "绑定端口成功" << endl;
}
//3. listen 侦听端口
//最大同时5个连接
if (SOCKET_ERROR == listen(_sock, 5)) {
cout << "监听端口失败" << endl;
}
else {
cout << "监听端口成功" << endl;
}
//4 accept 等待接受客户端连接
//这个socket接受的是客户端的信息
sockaddr_in _clientAddr = { };
int nAddrLen = sizeof _clientAddr;
//int nAddrLen = sizeof sockaddr_in;
//accept(_sock, (sockaddr*)&_clientAddr, &nAddrLen);
//接受客户端的信息 socket 存到这个socket里面
SOCKET _clientSocket = INVALID_SOCKET;
char buff[] = "hello client,I am Server";
while (true) {
_clientSocket = accept(_sock, (sockaddr*)&_clientAddr, &nAddrLen);
if (INVALID_SOCKET == _clientSocket) {
cout << "接收到无效客户端socket" << endl;
}
cout << "新客户端加入" << "IP为:" << inet_ntoa(_clientAddr.sin_addr) << endl;
//5. send 向客户端发送一条数据
send(_clientSocket, buff, strlen(buff) + 1, 0);
}
//6. 关闭套接字
closesocket(_sock);
WSACleanup();
return 0;
}
client:
#include <iostream>
#define WIN32_LEAN_AND_MEAN
#include<Windows.h>
#include<WinSock2.h>
//#define _WINSOCK_DEPRECATED_NO_WARNINGS
using namespace std;
int main()
{
//版本号
WORD ver = MAKEWORD(2, 2);
WSADATA dat;
WSAStartup(ver, &dat);
//1. 建立一个Socket
SOCKET _socket = socket(AF_INET, SOCK_STREAM, 0);
if (INVALID_SOCKET == _socket) {
cout << "错误,建立Socket失败" << endl;
}
else {
cout << "成功,建立Socket成功" << endl;
}
//2. 连接服务器 connect
sockaddr_in _sin = {};
_sin.sin_family = AF_INET;
_sin.sin_port = htons(4567);
_sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
if (INVALID_SOCKET == connect(_socket, (sockaddr*)(&_sin), sizeof _sin)) {
cout << "连接服务器失败" << endl;
}
else {
cout << "连接服务器成功" << endl;
}
//3. 接受服务器信息
char rebuff[256] = {};
//调用recv
int nlen = recv(_socket, rebuff, 256, 0);
if (nlen > 0) {
cout << "接受到数据" << endl;
printf("%s\n", rebuff);
}
//4. 关闭套接字
closesocket(_socket);
WSACleanup();
getchar();
return 0;
}
评论区