socket编程:bind()函数详解

文章目录

官方文档: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
    • 查看被使用的所有端口号
    • socket编程:bind()函数详解
  • netstat -ano|findstr “12345”
    • 检查我们要使用的端口是否被使用
    • 使用了就会显示使用的程序,未被
    • socket编程:bind()函数详解

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等效。

上一篇:Linux——网络基础socket套接字(协议、协议模型、IP、Port、网络字节序)


下一篇:socket三种地址结构