SOCKET 学习笔记

前言

面经中提到的epoll,涉及到了socket编程。为了深入了解epoll原理,需要首先了解socket编程。socket是进程间通信IPC,就算在网络中也是如此,所以说网络中通信的主体是进程,而不是计算机。socket学习内容一个是如何建立服务器和客户端,一个是如何使用socket API。

fd=socket(domain, type, protocol);

socket调用可以用来创建一个socket,例如
domain可以用来指定ipv4,type可以用来指定tcp,protocol一般是0。

  • domain
    domain是通信范围与通信地址的类型。有下面几个经典类型:
    UNIX IPV4 IPV6,分别对应的参数是AF_UNIX AF_INET AF_INET6。
    domain 的参数都是以AF开头的代表地址簇。PF开头的代表协议簇。本来设计是地址簇和协议簇是多对多的,但是后来实现过程中,一个协议簇和地址簇是一一对应的。所以基本上domain就是指定了协议簇,地址簇也被指定了。

  • type
    socket表示是流还是数据包,其实就是TCP还是UDP。如果是TCP就是SOCK_STREAM,如果是UDP就是SOCK_DGRAM

bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

该调用用于将socket绑定到一个地址上。之后可以发送TCP报文,在一些场合下也可以通过write发送UDP报文,但是只能在该socket上读取对等socket数据。

  • sockaddr
    该结构体有一个整形表示地址类型,然后后面跟着一个char数组。后面可以看到具体传进来的是根据使用场合的其他数据结构,但是是通用的

listen(int sockfd, int backlog)

将一个socket描述符标记为被动。可以被主动socket连接。backlog是用于限制等待连接的数量。

accept(int sockfd, struct sockaddr *addr, socklen_t * addrlen);

accept调用会阻塞并等待在文件描述符sockfd上的接入请求。一旦请求成功,会创建一个新的socket,这个新的socket与对方进行连接。

  • addr
    返回对方的地址
  • addrlen
    传入addr的长度,用于告知能够写入输入的最大长度。

connect(int sockfd, const struct sockaddr * addr, socklen_t addrlen);

将sockfd连接到addr所述的地址上。

close(int fd)

用于关闭连接

read write

用于对sockfd进行读入或读出

recvfrom(int sockfd, void *buffer, size_t length, int flags, struct sockaddr *src_addr, socklen_t *addrlen);

sendto(int sockfd, const void *buffer, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);

用于发送和接受udp报文。服务器端不能使用listen函数和accept函数,客户端不能使用connect函数。

unix domain

使用上面的API就可以实现本机上通过文件的通信。
unix domain所使用的sockaddr是sockaddr_run,如下表示:

struct sockaddr_un{
    sa_family_t sun_family;
    char sun_path[108];
}

网络字节序

网络字节顺序是按照大端来的,x86是小端结构。转换使用的是如下的函数进行的

  • htons
  • htonl
  • ntohs
  • ntohl
    h是host,n是net,s是16位,l是32位。s和l是short和long,虽然现在已经不再使用这样的标准了。

Internet socket 地址结构

网络下使用的socket地址是sockaddr_in,定义如下

struct sockaddr_in{
    sa_family_t sin_family;
    in_port_t sin_port;
    struct in_addr sin_addr;
    unsigned char __pad[X];
}

可以看出不一样的地方是后面的char数组变成了一个端口和地址。sin是socket Internet的简写,简写的和sun一样很差。

Internet socket 地址转换

字符串式的地址格式和二进制地址格式转换API:

inet_pton(int domain, const char *src, void *addrptr);

该函数用于将src中包含的字符串转换为网络字节的二进制地址,存入addrptr。p是presentation的意思,就是人类方便的地址。

const char * inet_ntop(int domain, const void *addrptr, char *dst_str, size_t len);

该函数执行网络字节的二进制地址转换为人类可读的地址,写入到dst_str中,缓冲区的大小有len传入。

getaddrinfo(const char *host, const char *service, const struct addrinfo *hints, struct **result);

该函数给定一个主机名和服务器名,返回socket地址和端口号。
getaddrinfo以host、service、hints参数作为输入,其中host参数包括一个主机名或一个以IPV4字符串。service是服务名或者是端口号。该函数的调用之后需要使用freeaddrinfo来释放空间。

getnameinfo(const struct sockaddr *addr, socklen_t addrlen, char *host, size_t hostlen, char *service, size_t servlen, int flags);

给定一个socket地址结构,返回一个主机和服务器名的字符串。

setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

sockfd是代表指向套接字的文件描述符。参数level制定了套接字选项所适用的协议。例如TCP或者是IP,这表示选项作用的套接字API层。一般来说,该选项会设置为SOL_SOCKET,表示作用于套接字API层。参数optname表示了我们期待设置的选项,optvalue是用来设置刚刚的选项的值,可以是整数或者是结构体的指针,指向了一个缓冲区,而参数optlen是刚刚那个指针所指向区域的大小。

例如,要设置sockfd为reuseaddr属性时,可以如下调用:

    int reuse = 1;
    if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1)
    {
        err_exit("setsockopt");
    }

getsockopt(int sockfd, int level, int optname, void *optval, socklen_t optlen);

用法和上面一样,只是获取而已。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容