当前位置:首页 > 行业动态 > 正文

c linux socket

Linux Socket 是 C 语言中用于网络通信的 API,支持多种协议。

在Linux系统中,C语言的Socket编程是一项关键技术,它允许应用程序通过网络进行通信,以下是关于C语言在Linux下进行Socket编程的详细解析:

基本概念

1、Socket定义:Socket是对网络上进程通信端点的抽象,是网络通信的基本单元,一个Socket就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。

2、类型

流式套接字(SOCK_STREAM):提供可靠的、有序的、无差错的数据传输服务,基于TCP协议实现。

数据报套接字(SOCK_DGRAM):提供无连接的、不可靠的数据传输服务,基于UDP协议实现。

编程步骤

1、创建Socket

使用socket()函数创建一个Socket描述符,该函数需要三个参数:协议族(如AF_INET表示IPv4)、Socket类型(如SOCK_STREAM或SOCK_DGRAM)和协议(通常为0,表示使用默认协议)。

示例代码:int socketfd = socket(AF_INET, SOCK_STREAM, 0);

2、绑定(Bind)

c linux socket

对于服务器端,需要使用bind()函数将Socket与一个特定的IP地址和端口号绑定在一起,这告诉操作系统该Socket将在哪个地址和端口上监听来自客户端的连接请求。

示例代码: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; bind(socketfd, (struct sockaddr )&server_addr, sizeof(server_addr));

3、监听(Listen)

服务器端调用listen()函数开始监听来自客户端的连接请求,该函数使Socket进入被动打开状态,准备接受外来连接。

示例代码:listen(socketfd, 5); // 第二个参数指定了最大挂起连接数

4、接受连接(Accept)

c linux socket

当有客户端发起连接请求时,服务器端调用accept()函数接受该请求,并返回一个新的Socket描述符用于与该客户端进行通信。

示例代码:int clientfd = accept(socketfd, NULL, NULL);

5、发送和接收数据

使用send()recv()函数在客户端和服务器之间发送和接收数据,这些函数可以通过Socket描述符来指定通信的另一端。

示例代码:char buffer[1024]; send(clientfd, "Hello, Client!", 15, 0); recv(clientfd, buffer, sizeof(buffer), 0);

6、关闭Socket

通信结束后,需要使用close()函数关闭Socket描述符以释放资源。

c linux socket

示例代码:close(socketfd);

注意事项

1、错误处理:在Socket编程中,需要对各种可能的错误情况进行处理,如创建Socket失败、绑定失败、监听失败等,可以通过检查函数返回值是否为负来判断是否发生错误,并使用perror()strerror()函数输出错误信息。

2、非阻塞模式:在某些情况下,可能需要将Socket设置为非阻塞模式以避免在读写操作时阻塞程序执行,可以使用fcntl()函数来设置Socket的阻塞模式。

示例代码

以下是一个简单的TCP服务器和客户端的示例代码:

服务器端

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
int main() {
    int socketfd, clientfd;
    struct sockaddr_in server_addr, client_addr;
    char buffer[1024];
    socklen_t client_len = sizeof(client_addr);
    // 创建Socket
    socketfd = socket(AF_INET, SOCK_STREAM, 0);
    if (socketfd < 0) {
        perror("socket() failed");
        exit(EXIT_FAILURE);
    }
    // 绑定
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8080);
    server_addr.sin_addr.s_addr = INADDR_ANY;
    if (bind(socketfd, (struct sockaddr )&server_addr, sizeof(server_addr)) < 0) {
        perror("bind() failed");
        close(socketfd);
        exit(EXIT_FAILURE);
    }
    // 监听
    if (listen(socketfd, 5) < 0) {
        perror("listen() failed");
        close(socketfd);
        exit(EXIT_FAILURE);
    }
    printf("Server is listening on port 8080...
");
    // 接受连接
    clientfd = accept(socketfd, (struct sockaddr )&client_addr, &client_len);
    if (clientfd < 0) {
        perror("accept() failed");
        close(socketfd);
        exit(EXIT_FAILURE);
    }
    printf("Client connected...
");
    // 接收数据
    int bytes_received = recv(clientfd, buffer, sizeof(buffer), 0);
    if (bytes_received < 0) {
        perror("recv() failed");
    } else {
        buffer[bytes_received] = '