int server_socket = socket(AF_INET, SOCK_STREAM, 0);
socket()
函数本身返回的是一个文件描述符, “Linux下一切皆文件”
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr("0.0.0.0");
server_addr.sin_port = htons(6969);
struct sockaddr_in
是一个专门用于表示 IPv4 地址的结构体。
除此之外,还有struct sockaddr
也是用来表示地址的结构体,但是sockaddr
是一个通用的地址结构体,可以用来表示不同类型的地址,比如 IPv4、IPv6、Unix 域套接字等。它是所有具体地址类型结构体的基类。
bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr));
listen(server_socket, 5);
其中的5,表示表示半连接与全连接的最大个数,简单来说就是:允许此服务端连接的客户端的最大数量
struct sockaddr_in client_adr;
socklen_t len = sizeof(client_adr);
accept(server_socket, (struct sockaddr*)&client_adr, &len);
// 打印信息
printf("client %s:%d connected\n",inet_ntoa(client_adr.sin_addr), ntohs(client_adr.sin_port));
若有客户端连接,则可使用accept()
函数接受连接,此函数会将连接的客户端信息放到client_adr
结构体中
可使用inet_ntoa(client_adr.sin_addr), ntohs(client_adr.sin_port)
获取客户端信息
recv(client_socket, recv_buf, 1024, 0)
对指定socket
接收数据,并放到recv_buf
中,最大值为1024,Flag为0(Flag: 略)
注意:
1. 若此函数返回: -1,则代表接受失败
2. 若此函数返回: 0,则代表对方关闭连接
close(client_socket);
close(server_socket);
//
// Created by JIN on 25-2-2.
//
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main()
{
// 1. 变量定义:套接字描述符、地址
int server_socket, client_socket;
struct sockaddr_in server_addr, client_adr;
// 2. 创建套接字
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == -1)
{
perror("create server_socket failed: ");
exit(0);
}
// 3. 初始化地址
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr("0.0.0.0");
server_addr.sin_port = htons(6969);
// 4. 套接字绑定地址
if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1)
{
perror("bind failed: ");
close(server_socket);
exit(0);
}
printf("socket bind successful\n");
// 5. 监听
listen(server_socket, 5);
printf("listening...\n");
// 6. 接收连接
socklen_t len = sizeof(client_adr);
client_socket = accept(server_socket, (struct sockaddr*)&client_adr, &len);
if (client_socket == -1)
{
perror("accept error: ");
close(client_socket);
close(server_socket);
exit(0);
}
printf("client %s:%d connected\n",inet_ntoa(client_adr.sin_addr), ntohs(client_adr.sin_port));
// 7. 接收数据
ssize_t recv_num = 0;
bool EXIT_FLAG = false;
char recv_buf[1024] = {0};
do
{
// 1. 接收数据
recv_num = recv(client_socket, recv_buf, 1024, 0);
/*
* 返回值:
* -1: 接收失败
* 0 : 对方关闭连接
*/
if (recv_num == -1)
{
perror("recv error: ");
continue;
}
else if (recv_num == 0)
{
printf("client close connect\n");
break;
}
// 2. 打印数据
printf("recv %ld bytes: %s\n", recv_num, recv_buf);
// 3. 判断退出FLAG
if (strcmp(recv_buf, "EXIT") == 0)
EXIT_FLAG = true;
// 4. 清空缓存
memset(recv_buf, 0, recv_num);
recv_num = 0;
}while (!EXIT_FLAG);
// 8. 关闭连接
close(client_socket);
close(server_socket);
printf("socket closed!\n");
return 0;
}