socket套接字
函数原型
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
功能
程序向内核提出创建一个基于内存的套接字描述符,用于网络通信。
参数说明
-
domain(协议域):
-
指定通信所使用的协议族(protocol family)。
-
常见的取值:
-
AF_INET
或PF_INET
:IPv4 互联网协议。 -
AF_INET6
或PF_INET6
:IPv6 互联网协议。 -
AF_UNIX
或PF_UNIX
:本地通信(文件系统套接字)。 -
其他协议族根据具体需求选择。
-
-
-
type(套接字类型):
-
指定套接字的通信语义。
-
常见的取值:
-
SOCK_STREAM
:面向连接的字节流套接字(如 TCP)。 -
SOCK_DGRAM
:无连接的数据报套接字(如 UDP)。 -
SOCK_RAW
:原始套接字(用于自定义协议,如 IP)。 -
SOCK_SEQPACKET
:有序分组套接字(较少使用)。
-
-
-
protocol(协议):
-
指定具体的协议。
-
通常设置为 0,表示根据
domain
和type
参数选择默认协议。 -
如果需要指定特定协议(如 IPPROTO_TCP、IPPROTO_UDP),可以显式设置。
-
返回值
-
成功时返回一个非负整数,表示新创建的套接字描述符。
-
失败时返回 -1,并设置
errno
错误码。
示例代码(创建 TCP 套接字)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main() {
int sockfd;
struct sockaddr_in servaddr;
// 创建 TCP 套接字
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
// 配置服务器地址
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); // 绑定到所有可用地址
servaddr.sin_port = htons(8080); // 服务端口
// 绑定套接字到地址
if (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
printf("Socket created and bound successfully.\n");
close(sockfd);
return 0;
}
常见错误码
-
EACCES
:权限不足,操作不被允许。 -
EAFNOSUPPORT
:指定的协议族不支持。 -
EINVAL
:无效的参数组合。 -
EMFILE
:进程已打开的文件描述符数量达到上限。 -
ENFILE
:系统已打开的文件描述符数量达到上限。 -
ENOBUFS
:内核内存不足,无法创建套接字。
注意事项
-
创建套接字后,需要根据通信类型(服务器或客户端)调用相应的函数(如
bind
、listen
、connect
、send
、recv
等)。 -
使用完毕后,记得调用
close
函数关闭套接字描述符,释放资源。 -
在多线程或并发环境中,套接字描述符需要正确管理,避免资源泄漏或竞争条件。