Linux_网络基础及编程流程

基本概念:

IP地址:IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异       标识主机

端口号:客户端可以通过ip地址找到对应的服务器端,但是服务器端有很多的端口,每个应用程序对应一个端口号,通过端口号,客户端才能真正的访问到该服务器。              识主机上运行的进程

网络字节序列:网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用大端排序方式。

网络通讯的主角:进程   
唯一标识一个进程的方法:IP地址+端口号

OSI的七层协议系统结构
应用层         --  网络服务与最终用户的一个接口
表示层         --  数据的表示、安全、压缩
会话层         --  建立、管理、终止会话
传输层         --  定义传输数据的协议端口号  以及流控和差错校验
网络层         --  进行逻辑地址寻址,实现不同网络之间的路径选择
数据链路层  --  建立逻辑连接、进行硬件地址寻址、差错校验
物理层         --  建立、维护、断开物理连接

TCP/IP协议四层模型及对应协议
应用层         --    HTTP   DNS  ping  Telnet
传输层         --    TCP  UDP
网络层         --    IP
数据链路层  --    ARP  RARP

 

TCP 服务器客户端编程流程
服务器端:
socket       --    创建套接字 ,用于监听客户端连接
bind           --    将监听套接字与服务器IP地址和端口号绑定
listen         --    启动监听
accept       --    获取一个客户端连接, 返回记录客户端连接的套接字
recv/send  --    接收或发送数据
close         --    关闭客户端连接或者关闭监听套接字(关闭服务器)
客户端:
socket       --    创建套接字, 用于和服务器连接与通讯
connect     --    发起连接
recv/send  --    接收或者发送数据
close         --    关闭连接

创建socket:int  socket(int  domain,  int  type,  int  protocol);
命令socket:int  bind(int sockfd, const struct sockaddr *addr, socklen_t  addrLen);
监听socket:int  listen(int sockfd, int  backlog);
接收链接:int accept(int sockfd, struct  sockaddr *addr, socklen_t *addrLen);
发起链接:int connect(int sockfd, struct  sockaddr *serAddr, socklen_t  addrLen);
数据读写:读数据:int recv(int  sockfd, void  *buff, size_t  buffSize, int  flag);
                  写数据:int write(int sockfd, const void *buff, size_t  dataLen, int  flag)
关闭连接:int   close(int   sockfd);
接受数据:int recv(int fd,void* buf,int len,size_t flags);
发送数据:int send(int fd,void* buf,size_t len,int flags)

编程中给定网络中进程的结构为:
struct sockaddr_in
{
    sa_family_t sin_family;   //地址簇
    short sin_port;                 //端口号
    struct in_addr sin_addr;  //IP地址
}
struct in_addr
{
    u_int32_t s_addr,          //32位无符号整数,将字符串表示的点分十进制转换为int
}

UPP 服务器客户端编程流程
服务器端:
socket      --    创建套接字 ,用于监听客户端连接
bind          --    将监听套接字与服务器IP地址和端口号绑定
recvfrom/sendto  --    接收或发送数据
close        --    关闭客户端连接或者关闭监听套接字(关闭服务器)
客户端:
socket      --    创建套接字, 用于和服务器连接与通讯
recvfrom/sendto  --    接收或者发送数据
close        --    关闭连接

int recvfrom(int fd,void* buf,size_t len,int flags,(struct sockaddr *)src_addr,int *addr_len);
int sendto(int fd,void* buf,size_t len,int flags,(struct sockaddr *)dest_addr,int *addr_len);

相关问题:
isten()第二个参数的意义:
创建套接字,随后绑定端口号,监听端口,套接字会等待连接,此时系统维护着两个队列,第一个队列存放的是已建立连接的套接字(完成三次握手的),第二个队列存放的是未建立连接的套接字(处在三次握手中的)。每次接受链接函数会将第一个队列中的套接字返回,进行通信,以完成网络传输。
listen()第二个参数的意义,在旧版本中表示两个队列的总和
listen()第二个参数的意义,在新版本中表示已完成连接的数量

connect()用于建立与指定socket的连接
调用connect函数时,如果服务端关闭,客户 端调用connect()函数时,发现阻塞在那里,而且利用ctrl+c信号去停止客户端程序时,需要等待一个较为长的时间才能响应了,约75秒的时间,如何防止 connect 长时间阻塞
步骤1: 设置非阻塞,启动连接
步骤2:判断可读和可写
             如果连接建立好了,,那么 sockfd 是可写的、 如果连接发生错误,sockfd 也是可读和可写的。
步骤3:使用 getsockopt 函数检查错误
getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &err, &len)
步骤4:重新将套接字设置为阻塞

先把套接字设置为非阻塞,因为在非阻塞情况下,connect的结果是立即返回的,然后我们再使用select或者poll等机制来检测套接字一定的时间,如果在超时时间内不可写,则认为connect失败,然后把套接字重新设置为阻塞。

accept()作用:accept函数主要用于服务器端,一般位于listen函数之后,默认会阻塞进程,直到有一个客户请求连接,建立好连接后,它返回的一个新的套接字socketfd_new ,此后,服务器端即可使用这个新的套接字socketfd_new与该客户端进行通信,而sockfd则继续用于监听其他客户端的连接请求。
accept返回的句柄建立的连接包括四部分:源IP、源端口号、目的IP、目的端口号。这样在一个应用程序中,就算和多个客户端建立连接,在收到数据后,应用程序通过目的IP和目的端口号也能区分是哪一条连接。

send()执行成功是否说明数据已经被成功发送到对端了
不能说明:用户调用send(data)将数据发送,内核会将data拷贝到内核空间的socket对应的缓冲中,而send()函数的返回值仅仅是表示本次send()调用中成功拷贝的字节数(用户空间->内核空间对应的sock缓冲队列)。send()执行成功的返回值与成功发送到接收端的数据量无直接关系 .

如何解决粘包 :
https://blog.csdn.net/m0_37829435/article/details/81747488
https://blog.csdn.net/axes/article/details/328543

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值