Linux服务器开发(基础篇):网络编程相关函数详解

引言

现在QQ、微信等聊天软件在我国得到了广泛使用,其火热程度可以说是:一天不吃饭也不能一天不聊微信。那么你可知道,手机上的软件是如何互相通信的呢?有计算机网络基础的读者,肯定很容易知道答案:通过网络套接字就可以通信了。

简单介绍

那啥是网络套接字呢?简单来说,它由三个部分组成:对方IP地址、使用的传输层协议(TCP或UDP)和端口号。其中IP地址能唯一标识出全球网络中联网了的一台主机,传输层协议是指通信双方以哪种数据传输的方式进行数据交互,端口号能代表是哪个程序(其实这里应该是进程)在进行通信。打个比方,IP地址代表了一对小情侣双方的家庭住址,通信双方代表了他们去对方家里时的交通方式,端口号则代表了这对小情侣,这样小情侣在串门的时候就不会走错,也不会找错恋爱对象了。

对Linux中一切皆文件的解释

在Linux系统层面的设计上,是使用了一种面向对象的设计思想,将一切外设当做文件,从而可以使用针对文件的那些操作。任何东西都挂在文件系统之上,即便即使它们不是文件,也以文件的形式来呈现,比如C语言当中的stdin、stdout等,在fprintf、read、write函数中,都可以通过文件描述符来对相应的设备(或者文件)进行输入输出;再比如proc、dev、socket等,都可以像操作文件一样对它们进行操作。
有了这个知识,接下来就可以来看看socket编程的相关函数了。

Socket相关函数定义及其功能

创建套接字并返回文件描述符

#include <sys/types.h> 
#include <sys/socket.h>
int socket(int domain, int type, int protocol);

参数含义:
domain:
AF_INET(现在基本上都是使用这个) 这是大多数用来产生socket的协议,使用TCP或UDP来传输,用IPv4的地址
AF_INET6 与上面类似,不过是来用IPv6的地址
AF_UNIX 本地协议,使用在Unix和Linux系统上,一般都是当客户端和服务器在同一台及其上的时候使用
type:
SOCK_STREAM 这个协议是按照顺序的、可靠的、数据完整的基于字节流的连接。这是一个使用最多的socket类型,这个socket是使用TCP来进行传输。
SOCK_DGRAM 这个协议是无连接的、固定长度的传输调用。该协议是不可靠的,使用UDP来进行它的连接。
SOCK_SEQPACKET该协议是双线路的、可靠的连接,发送固定长度的数据包进行传输。必须把这个包完整的接受才能进行读取。
SOCK_RAW socket类型提供单一的网络访问,这个socket类型使用ICMP公共协议。(ping、traceroute使用该协议)
protocol:
传0 表示使用默认协议。
返回值:
成功:返回指向新创建的socket的文件描述符,失败:返回-1,设置errno

将socket与IP地址、端口号等字段组成的结构体绑定

#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

参数含义:
sockfd:
服务器端socket文件描述符
addr:
构造出IP地址加端口号
addrlen:
sizeof(addr)长度
返回值:
成功返回0,失败返回-1, 设置errno

监听等待连接

#include <sys/types.h> 
#include <sys/socket.h>
int listen(int sockfd, int backlog);

参数含义:
sockfd:
服务器端socket文件描述符
backlog:
在Linux 系统中,它是指排队等待建立3次握手队列长度
返回值:
监听成功返回1,失败返回-1,设置errno

listen成功后,接收连接请求并返回一个新的socket用来通信

#include <sys/types.h> 	
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

参数含义:
sockdf:
服务器端socket文件描述符
addr:
传出参数,返回链接客户端地址信息,含IP地址和端口号
addrlen:
传入传出参数(值-结果),传入sizeof(addr)大小,函数返回时返回真正接收到地址结构体的大小
返回值:
成功返回一个新的socket文件描述符,用于和客户端通信,失败返回-1,设置errno

客户端与服务器端连接

#include <sys/types.h> 					
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

参数含义:
sockdf:
客户端socket文件描述符
addr:
传入参数,指定服务器端地址信息,含IP地址和端口号
addrlen:
传入参数,传入sizeof(addr)大小
返回值:
成功返回0,失败返回-1,设置errno

当connect成功后,客户端A的sockfd就已经能与服务器端B进行通信了,且服务器端B的accept函数也将成功返回一个sockfd,用来专门标识A与B连接,并可使用sockfd与A通信。值得注意的是,每当不同的客户端成功connect到服务器后,accept返回的sockfd是标识着不同的连接,每次都不一样。

出错处理函数定义及其功能

返回出错原因

#include <errno.h>
#include <string.h>
char *strerror(int errnum);

参数含义:
errnum:
传入参数,错误编号的值,一般取 errno 的值
返回值:
错误原因

向stderr(标准出错)输出错误原因

#include <stdio.h>
#include <errno.h>
void perror(const char *s);

参数含义:
s:传入参数,自定义的描述

常用文件操作函数定义及其功能

向fd所标识的文件中写入最大为count字节大小的buf

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);

参数含义:
fd:
文件描述符
buf:
写入的数据
count:
写入的最大长度
返回值:
成功:返回实际写入的字节数;
失败:返回 -1, 错误编号设置 errno

从fd所标识的文件中读取count个字节到buf里面

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);

参数含义:
fd:
文件描述符
buf:
存放读取数据的地方
count:
最大读取长度
返回值:
大于等于0:代表读取的长度
-1:出错了,设置errno

关闭fd所标识的文件(回收资源),成功后该文件描述符可以再次被分配使用

#include <unistd.h>
int close(int fd);

参数含义:
fd:
文件描述符
返回值:
成功: 0
失败: -1,设置errno

注意,某个socket不再使用时,我们应当用close将该资源回收,否则在并发环境下,可能会出现描述符被占用的错误,造成通信失败。
预告:下一篇将更新一个简单的聊天服务器案例,后续章节将对该服务器进行逐步改进。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱你是长久之计~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值