文章目录
官方文档:https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-bind
1. 函数原型
int bind(
SOCKET s,
const sockaddr *addr,
int namelen
);
2. 作用
给我们的socket绑定端口号与具体位置
**地址:**找到主机,只有一个
端口号:(就是一个整数 0-65535)
- 找到我们机器上对应的软件,比如QQ、浏览器等,都对应着自己的端口号
- 每一种通信的端口号是唯一的
- 同一个软件可能占有多个端口号
- 【0-1023】为系统保留占用端口号
- 21:FTP 文件传输协议服务
- 25:SMTP 简单邮件传输协议服务
- 80:HTTP服务
- 【1024-65535】我们可以自己用
- 默认使用10000+以后的
如何查看自己要用的端口号有没有被占用呢?
- 打开运行cmd输入netstat -ano
- 查看被使用的所有端口号
- netstat -ano|findstr “12345”
- 检查我们要使用的端口是否被使用
- 使用了就会显示使用的程序,未被
3. 使用
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>
// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
int main()
{
// Declare some variables
WSADATA wsaData;
int iResult = 0; // used to return function results
// the listening socket to be created
SOCKET ListenSocket = INVALID_SOCKET;
// The socket address to be passed to bind
sockaddr_in service;
//----------------------
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"Error at WSAStartup()\n");
return 1;
}
//----------------------
// Create a SOCKET for listening for
// incoming connection requests
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET) {
wprintf(L"socket function failed with error: %u\n", WSAGetLastError());
WSACleanup();
return 1;
}
//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port for the socket that is being bound.
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr("127.0.0.1");
service.sin_port = htons(27015);
//----------------------
// Bind the socket.
iResult = bind(ListenSocket, (SOCKADDR *) &service, sizeof (service));
if (iResult == SOCKET_ERROR) {
wprintf(L"bind failed with error %u\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
else
wprintf(L"bind returned success\n");
WSACleanup();
return 0;
}
4. 参数
-
s
- 标识未绑定套接字的描述符。
-
addr
-
指向要分配给绑定套接字的本地地址的sockaddr结构的指针。
-
下面的sockaddr结构和sockaddr_in 结构与IPv4一起使用。其他协议使用类似的结构。
-
struct sockaddr { ushort sa_family; char sa_data[14]; }; struct sockaddr_in { short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; };
-
in_addr
-
struct in_addr { union { struct { u_char s_b1; u_char s_b2; u_char s_b3; u_char s_b4; } S_un_b; struct { u_short s_w1; u_short s_w2; } S_un_w; u_long S_addr; } S_un; };
-
-
下面的sockaddr_in6 和sockaddr_in6_old 结构用于IPv6。
-
struct sockaddr_in6 { short sin6_family; u_short sin6_port; u_long sin6_flowinfo; struct in6_addr sin6_addr; u_long sin6_scope_id; }; typedef struct sockaddr_in6 SOCKADDR_IN6; typedef struct sockaddr_in6 *PSOCKADDR_IN6; typedef struct sockaddr_in6 FAR *LPSOCKADDR_IN6; struct sockaddr_in6_old { short sin6_family; u_short sin6_port; u_long sin6_flowinfo; struct in6_addr sin6_addr; };
-
-
namelen
- name参数所指向的值的长度(以字节为单位)。
5. 返回值
如果没有错误发生,则绑定返回零。 否则,它将返回SOCKET_ERROR,并且可以通过调用WSAGetLastError来检索特定的错误代码。
注意:
in_addr结构用于IPv4地址。
in_addr结构与基于IPv6的in6_addr结构的IPv4等效。