linux IPC socket
套接字是通讯端点的抽象
创建一个套接字
#include <sys/types.h>
#include <sys/socket.h> int socket(int domain, int type, int protocol);
返回值:成功文件(套接字)描述符,失败-1
domain:即协议域,又称为协议族(family)。常用的协议族有,AF_INET、AF_INET6、AF_LOCAL(或称AF_UNIX,Unix域socket)、AF_ROUTE等等。
协议族决定了socket的地址类型,在通信中必须采用对应的地址,如AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合、AF_UNIX决定了要用一个绝对路径名作为地址。
type:指定socket类型。常用的socket类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等(socket的类型有哪些?)。
protocal:故名思意,就是指定协议。常用的协议有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等
它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。
套接字通信是双向的。可以禁止一个套接字的I/O
#include <sys/socket.h> int shutdown(int sockfd, int how);
返回值:成功0,出错-
sockfd:套接字的描述符
how:三种SHUT_RD()关闭sockfd上的读功能
SHUT_WR()关闭sockfd上的写功能
SHUT_RDWR()关闭sockfd的读写功能
用来在处理器字节序和网络字节序之间实施转换的函数
#include <arpa/inet.h> uint32_t htonl(uint32_t hostlong);
返回值:以网络字节序表示的32位整数
uint16_t htons(uint16_t hostshort);
返回值:以网络字节序表示的16位整数
uint32_t ntohl(uint32_t netlong);
返回值:以主机字节序表示的32位整数
uint16_t ntohs(uint16_t netshort);
返回值:以主机字节序表示的16位整数
h表示主机字节序,n表示网络字节序,l表示长整型,s表示短整型
打印出能被人理解而不是计算机所理解的地址格式。同时支持IPv4和IPv6地址
#include <arpa/inet.h> const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
返回值:成功地址字符串指针,出错NULL
af:地址簇,仅支持AF_INET和AF_INET6
src:来源地址结构指针
dst:接收转换后的字符串
size:保存文本字符串的缓冲区大小 int inet_pton(int af, const char *src, void *dst);
返回值:成功1,格式无效0,出错-
af:地址簇,仅支持AF_INET和AF_INET6
src:转换的地址字符串
dst:转换后的地址结构指针
这个很常用,所有使用socket都需要用这两个函数转换,p应该是protocol,n应该是net吧。
例子
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h> int main(int argc, char *argv[])
{
char dst[];
int sockfd = socket(AF_INET, SOCK_STREAM, ); struct sockaddr_in serv;
memset(&serv, ,sizeof(struct sockaddr_in)); serv.sin_family = AF_INET;
serv.sin_port = htons(); if((inet_pton(AF_INET, "127.0.0.1", &serv.sin_addr.s_addr)) == )
printf("inet_pton error\n");
if((inet_ntop(AF_INET, &serv.sin_addr.s_addr, dst, sizeof(dst))) == NULL)
printf("inet_ntop error\n");
printf("dst=%s,sizeof(dst)=%d\n", dst, sizeof(dst)); bind(sockfd, (struct sockaddr *)&serv, sizeof(serv));
listen(sockfd, );
return ;
}
inet_pton
找到给定计算机系统的主机信息
#include <netdb.h> struct hostent *gethostent(void);
返回值:成功返回指针,出错NULL void sethostent(int stayopen);
stayopen:true就是TCP,否则UDP void endhostent(void);
能够采用一套相似的接口来获得网络名字和网络编号
#include <netdb.h> struct netent *getnetbyaddr(uint32_t net, int type);
struct netent *getnetbyname(const char *name);
struct netent *getnetent(void);
返回值:成功返回指针,出错NULL void setnetent(int stayopen);
void endnetent(void);
在协议名字和协议编号之间进行映射
#include <netdb.h> struct protoent *getprottobyname(const char *name);
struct protoent *getprotobynumber(int proto);
struct protoent *getprotoent(void);
返回值:成功返回指针,出错NULL void setprotoent(int stayopen);
void endprotoent(void);
服务是由地址的端口号部分表示的,每个服务由一个唯一的众所周知的端口号来支持。可以使用getservbyname将一个服务名映射到一个端口号,使用函数getservbyport将一个端口号映射到一个服务名,使用函数getservent顺序扫描服务数据库。
#include <netdb.h> struct servent *getservbyname(const char *name, const char *proto);
struct servent *getservbyport(int port, const char *proto);
struct servent *getservent(void);
返回值:成功返回指针,出错NULL void setservent(int stayopen);
void endservent(void);
将一个主机和一个服务名映射到一个地址
#include <sys/socket.h>
#include <netdb.h> int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints,
struct addrinfo **res);
返回值:成功0,出错非0错误码
node:向一个主机名(域名)或者地址串(IPv4的点分十进制串或者IPv6的16进制串)。
service:指向一个服务名或者10进制端口号数串。
hints:可以是一个空指针,也可以是一个指向某个addrinfo结构的指针
res:指向的变量已被填入一个指针,它指向的是由其中的ai_next成员串联起来的addrinfo结构链表 void freeaddrinfo(struct addrinfo *res);
addrinfo结构体
struct addrinfo
{
int ai_flags;
int ai_family; //AF_INET,AF_INET6,UNIX etc
int ai_socktype; //STREAM,DATAGRAM,RAW
int ai_protocol; //IPPROTO_IP, IPPROTO_IPV4, IPPROTO_IPV6 etc
size_t ai_addrlen;//length of ai_addr
char* ai_canonname; //full hostname
struct sockaddr* ai_addr; //addr of host
struct addrinfo* ai_next;
}
错误码需要调用函数来转换成错误消息
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h> const char *gai_strerror(int errcode);
将一个地址转换成一个额主机名和一个服务名
#include <sys/socke.h>
#include <netdb.h> int getnameinfo(const struct sockaddr *sa, socklen_t salen,
char *host, socklen_t hostlen,
char *serv, socklen_t servlen, int flags);
返回值:成功0,出错非0值
sa:指向包含协议地址的套接口地址结构,它将会被转换成可读的字符串,
salen:结构的长度,这个结构长度通常由accept、recvfrom、getsockname、getpeername
host:主机字符串
hostlen:长度
serv:服务器字符串
servlen:长度
flags:标志位可以有多个用与或
sockaddr结构体
16-9.c
#include "apue.h"
#if defined(SOLARIS)
#include <netinet/in.h>
#endif
#include <netdb.h>
#include <arpa/inet.h>
#if defined(BSD)
#include <sys/socket.h>
#include <netinet/in.h>
#endif void print_family(struct addrinfo *aip)
{
printf(" family ");
switch(aip->ai_family) {
case AF_INET:
printf("inet");
break;
case AF_INET6:
printf("inet6");
break;
case AF_UNIX:
printf("unix");
break;
case AF_UNSPEC:
printf("unspecified");
break;
default:
printf("unknown");
}
} void print_type(struct addrinfo *aip)
{
printf(" type ");
switch(aip->ai_socktype) {
case SOCK_STREAM:
printf("stream");
break;
case SOCK_DGRAM:
printf("datagram");
break;
case SOCK_SEQPACKET:
printf("seqpacket");
break;
case SOCK_RAW:
printf("raw");
break;
default:
printf("unknown (%d)", aip->ai_socktype);
}
} void print_protocol(struct addrinfo *aip)
{
printf(" protocol ");
switch(aip->ai_protocol) {
case :
printf("default");
break;
case IPPROTO_TCP:
printf("TCP");
break;
case IPPROTO_UDP:
printf("UDP");
break;
case IPPROTO_RAW:
printf("raw");
break;
default:
printf("unknown (%d)", aip->ai_protocol);
}
} void print_flags(struct addrinfo *aip)
{
printf("flags");
if(aip->ai_flags == ) {
printf("");
} else {
if(aip->ai_flags & AI_PASSIVE)
printf(" passive");
if(aip->ai_flags & AI_CANONNAME)
printf(" canon");
if(aip->ai_flags & AI_NUMERICHOST)
printf(" numhost");
if(aip->ai_flags & AI_NUMERICSERV)
printf(" numserv");
if(aip->ai_flags & AI_V4MAPPED)
printf(" v4mapped");
if(aip->ai_flags & AI_ALL)
printf(" all");
}
} int main(int argc, char *argv[])
{
struct addrinfo *ailist, *aip;
struct addrinfo hint;
struct sockaddr_in *sinp;
const char *addr;
int err;
char abuf[INET_ADDRSTRLEN]; if(argc != )
err_quit("usage: %s nodename service", argv[]);
hint.ai_flags = AI_CANONNAME;
hint.ai_family = ;
hint.ai_socktype = ;
hint.ai_protocol = ;
hint.ai_addrlen = ;
hint.ai_canonname = NULL;
hint.ai_addr = NULL;
hint.ai_next = NULL;
if((err = getaddrinfo(argv[], argv[], &hint, &ailist)) != )
err_quit("getaddrinfo error %s", gai_strerror(err));
for(aip = ailist; aip != NULL; aip = aip->ai_next) {
print_flags(aip);
print_family(aip);
print_type(aip);
print_protocol(aip);
printf("\n\thost %s", aip->ai_canonname?aip->ai_canonname:"-");
if(aip->ai_family == AF_INET) {
sinp = (struct sockaddr_in *)aip->ai_addr;
addr = inet_ntop(AF_INET, &sinp->sin_addr, abuf, INET_ADDRSTRLEN);
printf(" address %s", addr?addr:"unknown");
printf(" port %d", ntohs(sinp->sin_port));
}
printf("\n");
}
exit();
}
getaddrinfo
linux IPC socket的更多相关文章
- Linux IPC socket 广播,组播
getsockopt()/setsockopt() //获得sockfd指向的socket的属性 int getsockopt(int sockfd, int level, int optname, ...
- Linux IPC socket编程基础
头文件 #include<unistd.h> #include <sys/types.h> #include <sys/socket.h> #include< ...
- linux IPC socket(3)server简单写法
写server的一些流程总结 一.向内核申请一个socket TCP形式 sock_fd = socket(AF_INET, SOCK_STREAM, ); UDP形式 sfd = socket(AF ...
- linux IPC socket(2)
使用bind来关联地址和套接字 #include <sys/types.h> #include <sys/socket.h> int bind(int sockfd, cons ...
- Linux IPC实践(1) -- 概述
进程的同步与互斥 进程同步: 多个进程需要相互配合共同完成一项任务. 进程互斥: 由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种关系为进程的互斥;系统中某些 ...
- linux系统socket通信编程详解函数
linux socket编程之TCP与UDP TCP与UDP区别 TCP---传输控制协议,提供的是面向连接.可靠的字节流服务.当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之 ...
- linux ipc/its
linux进程间双向消息队列 server.c #include <stdio.h> #include <stdlib.h> #include <string.h> ...
- linux中socket的理解
对linux中socket的理解 一.socket 一般来说socket有一个别名也叫做套接字. socket起源于Unix,都可以用“打开open –> 读写write/read –> ...
- linux 客户端 Socket 非阻塞connect编程
开发测试环境:虚拟机CentOS,windows网络调试助手 非阻塞模式有3种用途 1.三次握手同时做其他的处理.connect要花一个往返时间完成,从几毫秒的局域网到几百 ...
随机推荐
- Mysql学习笔记(003)-案例讲解基础查询
案例讲解基础查询 #.下面的语句是否可以执行成功 SELECT last_name, first_name, salary AS sal FROM employees; #.下面的语句是否可以执行成功 ...
- leetcode-第14周双周赛-1274-矩形内船只的数目
题目描述: 自己的提交: # """ # This is Sea's API interface. # You should not implement it, or s ...
- 阿里云HBase推出普惠性高可用服务,独家支持用户的自建、混合云环境集群
HBase可以支持百TB数据规模.数百万QPS压力下的毫秒响应,适用于大数据背景下的风控和推荐等在线场景.阿里云HBase服务了多家金融.广告.媒体类业务中的风控和推荐,持续的在高可用.低延迟.低成本 ...
- <Jmeter入门不放弃>之<1.认识jmeter>
大家这里参考学习的时候,我就不在这里配截图了,因为需要你打开工具根据文档自己去找,,才有印象,大家一定要启动JMeter! 一.Jmeter是什么 由 Apache 组织开发,基于JAVA压力测试工具 ...
- subsequence 1
题目链接 题意:给你两个字符串都是数字,让你求第一个字符串的子序列中大于第二个字符串的个数. 思路:dp[i][j] 表示 str1的前i个,匹配 str2的前 j 个的种类数,那么 if(s[i] ...
- AcWing 241. 楼兰图腾 (树状数组)打卡
题目:https://www.acwing.com/problem/content/description/243/ 题意:给你n个点,问你 V 和 ^的图腾有多少个 思路:比如V 其实就是找当前点 ...
- 深入研究CSS
通常我们在学习CSS的时候,感觉很容易掌握,却常常在实际应用中碰到各式各样难以填补的“坑”,为避免大家受到同样的困惑与不解,本文详细讲解了CSS中优先级和Stacking Context等诸多高级特性 ...
- python locust-事件顺序
from locust import HttpLocust,TaskSet,task ''' 点击STOP,会停止测试,并调用所有当前执行的TaskSet的on_stop,但不会调用teardown函 ...
- 2019 ICPC Asia Nanchang Regional C And and Pair 找规律/位运算/dp
题意: 给定一个二进制表示的n,让你找满足如下要求的数对(i,j)的个数 $0 \leqslant j \leqslant i \leqslant n$ $ i & n = i $ $ i & ...
- springboot bootstrap.yml 和 application.yml
bootstrap.yml可以理解成系统级别的一些参数配置,这些参数一般是不会变动的 application.yml 可以用来定义应用级别的,如果搭配spring-cloud-config使用 app ...