Socket通过以下3个属性分类:域、连接类型和协议。
域包括UNIX文件域和因特网域等。
连接类型用来区分是TCP连接还是UDP连接。
协议包括http协议、ftp协议等。
(其他知识请参考计算机网络相关教材)
创建socket
int socket(int domain, int type, int protocol);
domain可以为以下值:
AF_UNIX unix文件域套接字
AF_INET internet域套接字
type可以为以下值:
SOCK_STREAM TCP连接
SOCK_DGRAM UDP连接
protocol表明选择哪种协议,一般为0(默认协议)。
成功则返回文件描述符,通过对该描述符的读写而进行通信。
失败返回-1。
地址信息
对于unix文件域套接字,地址信息用以下结构描述:
struct sockaddr_un {
sa_family_t sun_family; /* AF_UNIX */
char sun_path[]; /* pathname */
};
sun_family的值为AF_UNIX,sun_path为文件名。
对于internet域套接字则用以下结构描述地址信息:
struct sockaddr_in {
short int sin_family; /* AF_INET */
unsigned short int sin_port; /* Port number */
struct in_addr sin_addr; /* Internet address */
};
其中sin_family为AF_INET,sin_port为端口号,sin_addr为internet地址。
in_addr结构如下:
struct in_addr {
unsigned long int s_addr;
};
该结构用32位整型变量来存储ip地址。标准ip地址形式可以用inet_addr()
函数转换成32位整型值。如:
struct sockaddr_in address;
address.sin_addr.s_addr = inet_addr("127.0.0.1");
绑定socket
int bind(int socket, const struct sockaddr *address, size_t address_len);
该函数为描述符socket分配一个地址address,address_len为地址结构的长度。
成功返回0,失败返回-1。
创建socket队列
服务器程序必须创建一个队列来存储等待处理的请求。
int listen(int socket, int backlog);
该函数为服务器端得socket创建一个长度为backlog的队列。成功返回0,失败返回-1。
请求连接
int connect(int socket, const struct sockaddr *address, size_t address_len);
客户端程序向服务程序请求连接,服务器的地址信息存储在address所指向的空间中,
address_len为该段空间的长度。socket为客户端未绑定的套接字。
成功返回0,失败返回-1。
接受请求
int accept(int socket, struct sockaddr *address, size_t *address_len);
服务器端接受请求。socket参数必须是先前调用bind()绑定过的,并且必须调用过listen(),
使socket拥有待连接队列。客户端的地址信息将会写入address所指向的空间。address_len
参数必须被设置成所期望的长度。函数返回的时候,address_len会被设置成客户端地址的
实际长度。如果队列为空,则accept函数为阻塞。成功返回0,失败返回-1。
网络信息
获取主机信息:
struct hostent *gethostbyaddr(const void *addr, size_t len, int type);
struct hostent *gethostbyname(const char *name);
其中hostent如下:
struct hostent {
char *h_name; /* name of the host */
char **h_aliases; /* list of aliases (nicknames) */
int h_addrtype; /* address type */
int h_length; /* length in bytes of the address */
char **h_addr_list /* list of address (network order) */
};
利用这两个函数可以通过主机名或IP地址得到主机的网络信息。
例子:
获取服务信息
struct servent *getservbyname(const char *name, const char *proto);
struct servent *getservbyport(int port, const char *proto);
proto指明的服务的协议,"tcp"对应于SOCK_STREAM(tcp连接),"udp"对应于SOCK_DGRAM(udp连接)。
name为服务的名称,port为端口号。servent结构如下:
struct servent {
char *s_name; /* name of the service */
char **s_aliases; /* list of aliases (alternative names) */
int s_port; /* The IP port number */
char *s_proto; /* The service type, usually “tcp” or “udp” */
};
数据报(UDP)
int sendto(int sockfd, void *buffer, size_t len, int flags, struct sockaddr *to, socklen_t tolen);
通过sockfd向远端主机to发送长度为len的数据报buffer。在一般应用中flags为0。
int recvfrom(int sockfd, void *buffer, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);
通过sockfd从地址为from的主机读取长度为len的数据报到buffer中。flags可为0。
例子
Socket编程总结
最新推荐文章于 2023-04-18 21:37:24 发布