赞
踩
本文是作者在学习linux网络编程的时候所写的学习笔记,同时方便巩固自己学习的知识和网友们一起分享,尚若发现有什么不对的地方,欢迎指正。
网络是指将多个计算机或设备通过通信链路连接起来,以实现信息传输和资源共享的系统。网络可以是局域网(LAN),用于连接同一地理位置范围内的设备,也可以是广域网(WAN),用于连接不同地理位置范围内的设备。通过网络,用户可以通过电子邮件、网页浏览、文件传输等方式进行信息交流和资源共享。网络的基础是互联网,它是全球范围内的计算机网络,由各种硬件设备、协议和技术组成。互联网使得人们可以在全球范围内进行通信和访问各种信息资源。网络的发展和应用对现代社会的各个领域都有着重要的影响,包括通信、商务、教育、娱乐等。
// Create a socket
// Parameters:
// domain: communication domain (e.g., AF_INET for IPv4)
// type: socket type (e.g., SOCK_STREAM for TCP)
// protocol: specific protocol (e.g., 0 for default protocol)
// Return value:
// If successful, returns the socket file descriptor; otherwise, returns -1
int socket(int domain, int type, int protocol);
#include <sys/socket.h>
函数是在网络编程中用于创建套接字的系统调用函数。套接字是实现网络通信的一种机制,它可以用于在不同的计算机之间进行数据传输。
int socket(int domain, int type, int protocol);
int socket(int domain, int type, int protocol);
下面我将列举出15个协议族,并且以表格的形式列举出来。注意,这只是一些常见的通信域,实际上还有其他更多的特定协议族可供选择:
man page里面数字的含义,即ip(7)之中7的含义
Protocol Family Name(协议族名字) | Description(说明) | Chinese(中文) | man page(手页册) | Commonly Used |
---|---|---|---|---|
AF_INET | IPv4 Internet protocols | IPv4网络协议 | ip(7) | * |
AF_INET6 | IPv6 Internet protocols | IPv6网络协议 | ipv6(7) | * |
AF_UNIX | UNIX domain protocols | UNIX域协议 | unix(7) | * |
AF_PACKET | Low level packet interface protocols | 底层数据包接口协议 | packet(7) | * |
AF_BLUETOOTH | Bluetooth protocols | 蓝牙协议 | bluetooth(7) | * |
AF_NETLINK | Linux Kernel user interface device protocols | Linux 内核用户界面设备协议 | netlink(7) | * |
AF_LOCAL | Local to host protocols | 本地协议 | unix(7) | |
AF_X25 | ITU-T X.25 / ISO-8208 protocol family | X.25协议 | x25(7) | |
AF_AX25 | Amateur radio AX.25 protocol | 业余无线电AX.25协议 | ax25(7) | * |
AF_ATMPVC | Access to raw ATM PVCs | ATM PVC协议 | atmarp(7) | |
AF_APPLETALK | AppleTalk | AppleTalk协议 | ddp(7) | |
AF_ECONET | Acorn Econet | Acorn Econet协议 | econet(7) | |
AF_IPX | IPX - Novell protocols | IPX协议 | ipx(7) | |
AF_ROSE | Amateur Radio X.25 PLP | 业余无线电X.25 PLP协议 | rose(7) | |
AF_NETROM | Amateur radio NET/ROM protocol | 业余无线电NET/ROM协议 | netrom(7) | |
AF_SECURITY | Security Attribute-based Access Control Kernel Extensions | 安全属性访问控制内核扩展 | security(7) |
int socket(int domain, int type, int protocol);
对于网络编程,最常用的是SOCK_STREAM(TCP协议)和SOCK_DGRAM(UDP协议)两种socket类型,分别对应TCP和UDP协议。如果你有任何其他问题,请随时提问!
Socket Type | Description |
---|---|
SOCK_STREAM | 提供面向连接的、可靠的数据传输服务。使用TCP协议。 |
SOCK_DGRAM | 提供无连接的、不可靠的数据传输服务。使用UDP协议。 |
SOCK_SEQPACKET | 提供面向连接的、可靠的数据传输服务。与SOCK_STREAM不同的是,保留了数据的边界(即数据报之间不会混淆)。 |
SOCK_RAW | 提供原始网络协议访问。需要应用程序自行构造协议头部。 |
SOCK_RDM | 提供面向连接的、可靠的数据传输服务,但是保留数据的边界。这个类型的socket基本上已经被废弃了。 |
SOCK_DCCP | 提供基于数据报的数据传输服务,使用DCCP协议。 |
SOCK_PACKET | 提供原始以太网数据包的访问,需要特权权限。已经过时。 |
SOCK_CLOEXEC | 在创建socket时设置close-on-exec标志位,使得socket在exec调用时自动关闭。 |
SOCK_NONBLOCK | 在创建socket时设置non-blocking标志位,使得socket的I/O操作变为非阻塞。 |
SOCK_PACKET已经被废弃了。在Linux 2.2版本以前,SOCK_PACKET是一种特殊的socket类型,可以用于访问网络驱动程序,但是需要特权权限。在Linux 2.2版本之后,SOCK_PACKET被替换为了SOCK_RAW,SOCK_RAW可以提供相同的功能,而且不需要特权权限。
在Linux 2.4版本之后,SOCK_PACKET被重新引入了,但这次它只是作为一种socket族别(socket family),而不是一种socket类型。也就是说,现在我们可以使用PF_PACKET来创建一个SOCK_PACKET socket了,而不再使用SOCK_PACKET socket类型。
请注意,PF_PACKET是一种特殊的socket族别,用于在数据链路层上发送和接收数据。它可以与SOCK_RAW结合使用,来构造和解析以太网帧、ARP报文等,从而实现更灵活的网络编程。
int socket(int domain, int type, int protocol);
当调用socket函数时,如果protocol参数设置为0,则会选择默认的协议。默认的协议通常是与给定的域和套接字类型最匹配的协议。
但是,有些域和套接字类型支持多种协议。在这种情况下,可以使用protocol参数来选择特定的协议。例如,在IPv4中,SOCK_STREAM套接字类型支持TCP和SCTP协议,SOCK_DGRAM套接字类型支持UDP和DCCP协议。如果我们要使用SCTP协议而不是TCP协议来创建一个SOCK_STREAM套接字,则可以将protocol参数设置为IPPROTO_SCTP。
需要注意的是,不同的操作系统可能支持不同的协议,因此要根据具体的环境来选择正确的协议。此外,还需要了解不同协议之间的性能和特性差异,以确保选择的协议适合应用程序的需求。
当调用socket函数时,protocol参数可以根据不同的domain和type组合来选择适合的协议。以下是一些常见的domain和type组合以及对应的protocol:
Domain | Type | Protocol |
---|---|---|
AF_INET | SOCK_STREAM | IPPROTO_TCP (TCP协议) |
AF_INET | SOCK_DGRAM | IPPROTO_UDP (UDP协议) |
AF_INET6 | SOCK_STREAM | IPPROTO_TCP (TCP协议) |
AF_INET6 | SOCK_DGRAM | IPPROTO_UDP (UDP协议) |
AF_UNIX | SOCK_STREAM | 0 (默认协议,通常是UNIX域套接字) |
AF_UNIX | SOCK_DGRAM | 0 (默认协议,通常是UNIX域套接字) |
这只是一些常见的组合,实际上还有很多的组合。
在Linux系统下,C语言的套接字函数(如socket()、bind()、listen()等)的返回值类型通常是int型。这些函数的返回值表示函数执行的结果或错误代码。如果函数执行成功,则返回一个非负的套接字描述符,用于后续的套接字操作。如果函数执行失败,则返回-1,并且可以通过检查全局变量errno来获取具体的错误代码。
常见的套接字函数返回值为-1的错误代码包括:
// Set socket options
// Parameters:
// sockfd: socket file descriptor
// level: protocol level of the option (e.g., SOL_SOCKET for socket-level options)
// optname: the name of the option to be set
// optval: pointer to the memory area where the option value is stored
// optlen: the length of the option value in bytes
// Return value:
// If successful, returns 0; otherwise, returns -1
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
#include <sys/socket.h>
setsockopt()函数是一个用于设置套接字选项的系统调用函数。它允许应用程序在已打开的套接字上设置各种选项,以控制套接字的行为。
参数说明:
int optval = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0)
{
perror("setsockopt failed");
exit(EXIT_FAILURE);
}
这个示例中, SO_REUSEADDR 选项被设置为1,表示允许地址重用。这对于服务器程序在关闭后立即重新启动时很有用。
struct timeval timeout;
timeout.tv_sec = 5; // 5秒
timeout.tv_usec = 0;
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0)
{
perror("setsockopt failed");
exit(EXIT_FAILURE);
}
在这个示例中, SO_RCVTIMEO 选项被设置为5秒,表示在接收数据时最多等待5秒钟。如果在指定时间内没有接收到数据, recv() 函数将返回超时错误。
int optval = 8192; // 8KB
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &optval, sizeof(optval)) < 0)
{
perror("setsockopt failed");
exit(EXIT_FAILURE);
}
这个示例中, SO_RCVBUF 选项被设置为8KB,表示接收缓冲区的大小为8KB。
setsockopt()函数的返回值是一个整数,表示函数执行的结果。如果函数执行成功,则返回值为0;如果函数执行失败,则返回值为-1,并且可以通过检查全局变量errno来获取具体的错误代码。常见的错误代码包括:
// Bind the socket to an address
// Parameters:
// sockfd: socket file descriptor
// addr: pointer to the address structure to bind to
// addrlen: length of the address structure in bytes
// Return value:
// If successful, returns 0; otherwise, returns -1
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
#include <sys/types.h>
#include <sys/socket.h>
在 bind 函数中,有三个参数需要说明:
// Set the socket to listen for incoming connections
// Parameters:
// sockfd: socket file descriptor
// backlog: maximum number of pending connections in the waiting queue
// Return value:
// If successful, returns 0; otherwise, returns -1
int listen(int sockfd, int backlog);
#include <sys/types.h>
#include <sys/socket.h>
listen 函数接受两个参数:
listen 函数返回一个整数值,表示函数执行的结果。具体含义如下:
// Accept a client connection request and create a new socket to handle the connection
// Parameters:
// sockfd: socket file descriptor
// addr: pointer to the structure that will hold the client address information
// addrlen: pointer to the length of the structure in bytes
// Return value:
// If successful, returns the new socket file descriptor; otherwise, returns -1
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
#include <sys/types.h>
#include <sys/socket.h>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。