当前位置: 首页 > 工具软件 > C++ Sockets > 使用案例 >

C/C++ Socket

丌官凯康
2023-12-01

Socket

创建 socket

#include <sys/socket.h>
#include <netinet/in.h>

int socket(int domain, int type, int protocol);

参数:domain ==》 填 AF_INET 表示 IPv4
type ==》 SOCK_STREAM 表示 tcp 连接
SOCK_DGRAM 表示 udp 连接
SOCK_SEQPACKET ==》 提供连续可靠的数据包连接(我不知道是什么协议)
protocol ==》 一般填0

返回:成功 >= 0 失败 < 0

服务端 socket 的绑定

#include <sys/socket.h>

int bind(int socket, const struct sockaddr *address, socklen_t address_len);

参数:socket ==》 socket() 创建的 socket
struct sockaddr *address ==》配置 socket 的结构体地址,具体见下
address_len ==》 struct sockaddr 的大小,就是上一个结构体参数的 sizeof

返回:成功 0 失败 -1

结构体 sockaddr_in :

struct sockaddr_in
  {
    __SOCKADDR_COMMON (sin_);
    in_port_t sin_port;			/* Port number.  */
    struct in_addr sin_addr;		/* Internet address.  */

    /* Pad to size of `struct sockaddr'.  */
    unsigned char sin_zero[sizeof (struct sockaddr)
			   - __SOCKADDR_COMMON_SIZE
			   - sizeof (in_port_t)
			   - sizeof (struct in_addr)];
  };

使用如下方式设置结构体:
IPv4:serverAddr.sin_family = AF_INET;
结构体变量.sin_addr.s_addr 赋值:
头文件定义的代表 “0.0.0.0”:#define INADDR_ANY ((in_addr_t) 0x00000000)
inet_aton(INADDR_ANY, &结构体变量.sin_addr);
结构体变量.sin_addr.s_addr = htonl(INADDR_ANY);
结构体变量.sin_addr.s_addr = inet_addr(IPv4字符串);
定义port:
serverAddr.sin_port = htons(端口号数字);
serverAddr.sin_port = atoi(端口号字符串)

补充:inet_ntoa(结构体变量.sin_addr) 返回值是IPv4字符串

示例:

struct sockaddr_in serverAddr;
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddr.sin_port = htons(port);

bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr));

服务端的监听模式

#include <sys/socket.h>

int listen(int socket, int backlog);

参数:socket ==》 bind 完成后的 socket
backlog ==》 等待监听客户端阻塞数量(客户端请求发现服务端socket暂时有其他人用等待)

返回:成功 0 失败 -1

服务端连接客户端

#include <sys/socket.h>

int accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len);

参数:socket ==》 服务端 listen 后的socket
sockaddr *restrict address ==》 结构体地址,见上,使用方式见下
socklen_t *restrict address_len ==》 结构体大小的地址,见上,使用方式见下

返回:返回一个客户端 socket

使用

struct sockaddr_in clntAddr; //结构体,存放客户端socket信息
socklen_t clntAddrSize = sizeof(clntAddr); // 结构体大小
int clntSocket = 0; //客户端socket

clntSocket = accept(serverSocket, (struct sockaddr*)&clntAddr, &clntAddrSize);

服务端接收客户端消息

#include <sys/socket.h>

ssize_t recv(int socket, void *buffer, size_t length, int flags);

参数:socket ==》 accept 返回的客户端 socket
buffer ==》 接收客户端消息存放在本地的字符数组指针
length ==》 buffer 最大空间大小
flags ==》 一般 0

返回:成功 接收字节数 失败 < 0 在等待协议接收数据时网络中断 返回0

内容保存在 buffer 里面

示例

int msgLen = recv(clntSocket, buf, BUFSIZE, 0);

服务端发送消息给客户端

同客户端发送,见下,socket 为acce 返回的客户端socket

客户端 socket 连接服务端

#include <sys/socket.h>

int connect(int socket, const struct sockaddr *address, socklen_t address_len);

参数:socket ==》 使用 socket() 创建的客户端 socket
struct sockaddr *address ==》 结构体地址,见下
address_len ==》 结构体大小,使用见下

返回:成功 0 失败 -1

结构体 sockaddr_in :

struct sockaddr_in
  {
    __SOCKADDR_COMMON (sin_);
    in_port_t sin_port;			/* Port number.  */
    struct in_addr sin_addr;		/* Internet address.  */

    /* Pad to size of `struct sockaddr'.  */
    unsigned char sin_zero[sizeof (struct sockaddr)
			   - __SOCKADDR_COMMON_SIZE
			   - sizeof (in_port_t)
			   - sizeof (struct in_addr)];
  };

使用如下方式设置结构体:
IPv4:serverAddr.sin_family = AF_INET;
结构体变量.sin_addr.s_addr 赋值:
头文件定义的代表 “0.0.0.0”:#define INADDR_ANY ((in_addr_t) 0x00000000)
inet_aton(INADDR_ANY, &结构体变量.sin_addr);
结构体变量.sin_addr.s_addr = htonl(INADDR_ANY);
结构体变量.sin_addr.s_addr = inet_addr(IPv4字符串);
定义port:
serverAddr.sin_port = htons(端口号数字);
serverAddr.sin_port = atoi(端口号字符串)

补充:inet_ntoa(结构体变量.sin_addr) 返回值是IPv4字符串

示例:

struct sockaddr_in serverAddr;
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr("172.17.0.2");
serverAddr.sin_port = htons(8088);

int state = connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr));

客户端给服务端发送数据

#include <sys/socket.h>

ssize_t send(int socket, const void *buffer, size_t length, int flags);

参数:socket ==》 客户端的 socket
buffer ==》 发送的内容放到 buffer 字符数组里面
length ==》 发送的长度
flags ==》一般 0

返回:成功 发送的长度 失败 -1

客户端接收服务端消息

同服务端接收,见上,socket 为 客户端自己的socket

 类似资料: