返回

Linux网络编程之socket详解:编写出色的通信软件

后端

在计算机网络领域,socket函数是构建网络应用程序的基础。本文将详细介绍Linux网络编程之socket函数的用法,并以客户端和服务端间TCP通信的源码实现为例,详细讲解了socket函数的使用方法,同时还提供了端口状态监测的实现示例,帮助您更好地理解socket函数的应用。如果您想要编写出色的通信软件,本文将为您提供全面的指导。

1. socket函数讲解

socket函数是Linux系统中用于创建套接字的函数。套接字是应用程序之间进行通信的端点,它为应用程序提供了一种方法来发送和接收数据。socket函数的语法如下:

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

其中,

  • domain:指定套接字的域,常用的域有AF_INET(IPv4)和AF_INET6(IPv6)。
  • type:指定套接字的类型,常用的类型有SOCK_STREAM(TCP)和SOCK_DGRAM(UDP)。
  • protocol:指定套接字使用的协议,常用的协议有IPPROTO_TCP(TCP)和IPPROTO_UDP(UDP)。

2. 客户端和服务端间TCP通信的源码实现

在客户端和服务端间进行TCP通信时,需要使用socket函数来创建套接字,并使用connect()函数和accept()函数来建立连接。客户端使用connect()函数连接到服务端的端口,服务端使用accept()函数接受客户端的连接请求。连接建立后,客户端和服务端就可以通过套接字进行数据传输。

以下是如何使用socket函数实现客户端和服务端间TCP通信的源码:

// 服务端代码

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

int main()
{
    int server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (server_socket == -1)
    {
        perror("socket");
        return -1;
    }

    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8080);
    server_addr.sin_addr.s_addr = INADDR_ANY;

    if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
    {
        perror("bind");
        return -1;
    }

    if (listen(server_socket, 10) == -1)
    {
        perror("listen");
        return -1;
    }

    int client_socket = accept(server_socket, NULL, NULL);
    if (client_socket == -1)
    {
        perror("accept");
        return -1;
    }

    char buffer[1024];
    while (1)
    {
        int recv_len = recv(client_socket, buffer, sizeof(buffer), 0);
        if (recv_len == -1)
        {
            perror("recv");
            return -1;
        }
        else if (recv_len == 0)
        {
            printf("Client disconnected.\n");
            break;
        }

        printf("Received from client: %s", buffer);

        int send_len = send(client_socket, buffer, recv_len, 0);
        if (send_len == -1)
        {
            perror("send");
            return -1;
        }
    }

    close(client_socket);
    close(server_socket);

    return 0;
}

// 客户端代码

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

int main()
{
    int client_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (client_socket == -1)
    {
        perror("socket");
        return -1;
    }

    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8080);
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    if (connect(client_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
    {
        perror("connect");
        return -1;
    }

    char buffer[1024];
    while (1)
    {
        printf("Enter a message to send: ");
        scanf("%s", buffer);

        int send_len = send(client_socket, buffer, strlen(buffer), 0);
        if (send_len == -1)
        {
            perror("send");
            return -1;
        }

        int recv_len = recv(client_socket, buffer, sizeof(buffer), 0);
        if (recv_len == -1)
        {
            perror("recv");
            return -1;
        }
        else if (recv_len == 0)
        {
            printf("Server disconnected.\n");
            break;
        }

        printf("Received from server: %s", buffer);
    }

    close(client_socket);

    return 0;
}

3. 单线程BIO实现

在Linux网络编程中,BIO(Blocking I/O)是一种常见的I/O模型。BIO模型采用阻塞式I/O操作,即当应用程序调用I/O函数时,应用程序会一直阻塞,直到I/O操作完成。

以下是如何使用BIO模型实现客户端和服务端间TCP通信的源码:

// 服务端代码

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

int main()
{
    int server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (server_socket == -1)
    {
        perror("socket");
        return -1;
    }

    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8080);
    server_addr.sin_addr.s_addr = INADDR_ANY;

    if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
    {
        perror("bind");
        return -1;
    }

    if (listen(server_socket, 10) == -1)
    {
        perror("listen");
        return -1;
    }

    int client_socket = accept(server_socket, NULL, NULL);
    if (client_socket == -1)
    {
        perror("accept");
        return -1;
    }

    char buffer[1024];
    while (1)
    {
        int recv_len = recv(client_socket, buffer, sizeof(buffer), 0);
        if (recv_len == -1)
        {
            perror("recv");
            return -1;
        }
        else if (recv_len == 0)
        {
            printf("Client disconnected.\n");
            break;
        }

        printf("Received from client: %s", buffer);

        int send_len = send(client_socket, buffer, recv_len, 0);
        if (send_len == -1)
        {
            perror("send");
            return -1;
        }
    }

    close(client_socket);
    close(server_socket);

    return 0;
}

// 客户端代码

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

int main()
{
    int client_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (client_socket == -1)
    {
        perror("socket");
        return -1;
    }

    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_