HCRM博客

如何在CentOS上创建和使用Socket?

什么是CentOS socket

在CentOS操作系统中,Socket是一种用于进程间通信(IPC)的机制,它允许不同主机上的进程通过网络进行通信,Socket可以看作是一种特殊的文件描述符,它提供了一种标准的文件I/O操作接口,让应用程序能够方便地进行网络数据传输。

工作原理

1、服务端:首先通过socket()函数创建一个套接字,然后使用bind()函数将该套接字与本地地址和端口号绑定,接着调用listen()函数使套接字进入监听状态,等待客户端的连接请求,当有客户端发起连接时,accept()函数会接受连接并返回一个新的套接字,用于与客户端进行数据交互。

如何在CentOS上创建和使用Socket?-图1
(图片来源网络,侵权删除)

2、客户端:同样先通过socket()函数创建一个套接字,然后使用connect()函数向服务端的地址和端口发起连接请求,连接成功后,客户端就可以通过套接字与服务端进行数据的发送和接收。

3、数据传输:建立连接后,服务端和客户端可以通过send()recv()函数进行数据的发送和接收,实现双向的数据交换。

4、关闭连接:当通信完成后,双方需要调用close()函数关闭套接字,释放资源

常用函数及参数

1、socket():创建一个新的套接字,其原型为int socket(int domain, int type, int protocol),其中domain指定协议族,如AF_INET表示IPv4;type指定套接字类型,如SOCK_STREAM表示流式套接字,SOCK_DGRAM表示数据报套接字;protocol通常设置为0,表示使用默认协议。

2、bind():将套接字与指定的IP地址和端口号绑定,原型为int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen),其中sockfd是套接字描述符,addr是指向包含IP地址和端口号的结构体的指针,addrlen是该结构体的大小。

3、listen():使套接字进入监听状态,等待客户端的连接请求,原型为int listen(int sockfd, int backlog),其中sockfd是套接字描述符,backlog指定了等待连接的最大队列长度。

如何在CentOS上创建和使用Socket?-图2
(图片来源网络,侵权删除)

4、accept():接受客户端的连接请求,返回一个新的套接字描述符,原型为int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen),其中sockfd是监听套接字描述符,addraddrlen用于获取客户端的IP地址和端口号等信息。

5、connect():主动发起到服务器的连接,原型为int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen),其中sockfd是套接字描述符,addr是指向包含服务器IP地址和端口号的结构体的指针,addrlen是该结构体的大小。

6、send():通过套接字发送数据,原型为ssize_t send(int sockfd, const void *buf, size_t len, int flags),其中sockfd是套接字描述符,buf是要发送的数据缓冲区,len是数据的长度,flags用于指定发送选项。

7、recv():通过套接字接收数据,原型为ssize_t recv(int sockfd, void *buf, size_t len, int flags),其中sockfd是套接字描述符,buf是用于存储接收数据的缓冲区,len是缓冲区的长度,flags用于指定接收选项。

8、close():关闭套接字,原型为int close(int sockfd),其中sockfd是套接字描述符。

示例代码

以下是一个简单的基于TCP的CentOS socket编程示例,实现了一个客户端和服务端的基本通信:

如何在CentOS上创建和使用Socket?-图3
(图片来源网络,侵权删除)

服务端代码

```c++

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <unistd.h>

#define PORT 8080

int main() {

int server_fd, new_socket;

struct sockaddr_in address;

int opt = 1;

int addrlen = sizeof(address);

char buffer[1024] = {0};

char *hello = "Hello from server";

// 创建socket文件描述符

if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {

perror("socket failed");

exit(EXIT_FAILURE);

}

// 强制附加套接字到端口8080

if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {

perror("setsockopt");

exit(EXIT_FAILURE);

}

address.sin_family = AF_INET;

address.sin_addr.s_addr = INADDR_ANY;

address.sin_port = htons(PORT);

// 将套接字绑定到上述端口

if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0) {

perror("bind failed");

exit(EXIT_FAILURE);

}

if (listen(server_fd, 3) < 0) {

perror("listen");

exit(EXIT_FAILURE);

}

if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0) {

perror("accept");

exit(EXIT_FAILURE);

}

read(new_socket , buffer, 1024);

printf("%s

",buffer );

send(new_socket , hello , strlen(hello) , 0 );

printf("Hello message sent

");

close(server_fd);

return 0;

客户端代码:
```c++
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define PORT 8080
int main() {
    struct sockaddr_in serv_addr;
    int sock = 0;
    char *hello = "Hello from client";
    char buffer[1024] = {0};
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        printf("
 Socket creation error 
");
        return 1;
    }
  
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);
      
    if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0) {
        printf("
Invalid address/ Address not supported 
");
        return 1;
    }
  
    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        printf("
Connection Failed 
");
        return 1;
    }
    send(sock , hello , strlen(hello) , 0 );
    printf("Hello message sent
");
    int valread = read( sock , buffer, 1024);
    printf("%s
",buffer );
    close(sock);
    return 0;
}

FAQs

1、Q: CentOS socket编程中,如何选择合适的协议族和套接字类型?

A: 选择协议族主要取决于应用的网络环境,如果是在同一台主机上进行进程间通信,可以选择AF_UNIX协议族;如果是在不同主机之间进行通信,则根据网络层协议选择AF_INET(IPv4)或AF_INET6(IPv6),套接字类型的选择则根据应用的需求来决定,如果需要可靠的、面向连接的通信,如文件传输、邮件等,应选择流式套接字(SOCK_STREAM);如果对实时性要求较高,且能容忍一定的数据丢失,如视频直播、实时聊天等,可以选择数据报套接字(SOCK_DGRAM)。

2、Q: CentOS socket编程中,如何处理多个客户端的并发连接?

A: 可以使用多线程或多进程的方式来处理多个客户端的并发连接,对于每个客户端的连接请求,服务端在接受连接后,可以创建一个新的线程或进程来专门处理该客户端的数据交互,这样主线程或主进程就可以继续监听其他客户端的连接请求,从而实现并发处理。

本站部分图片及内容来源网络,版权归原作者所有,转载目的为传递知识,不代表本站立场。若侵权或违规联系Email:zjx77377423@163.com 核实后第一时间删除。 转载请注明出处:https://blog.huochengrm.cn/pc/22229.html

分享:
扫描分享到社交APP
上一篇
下一篇