Linux系统编程—网络编程—socket编程步骤

Posted 是光哥呀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux系统编程—网络编程—socket编程步骤相关的知识,希望对你有一定的参考价值。

TCP/UDP对比

  1. TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前 不需 要建立连接
  2. TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
  3. TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的
    UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
  4. 每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
  5. TCP首部开销20字节;UDP的首部开销小,只有8个字节
  6. TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道

端口号作用
一台拥有IP地址的主机可以提供许多服务,比如Web服务、FTP服务、SMTP服务等

这些服务完全可以通过1个IP地址来实现。那么,主机是怎样区分不同的网络服务呢?显然不能只靠IP地址,因为IP 地址与网络服务的关系是一对多的关系。

实际上是通过“IP地址+端口号”来区 分不同的服务的。
端口提供了一种访问通道,
服务器一般都是通过知名端口号来识别的。例如,对于每个TCP/IP实现来说,FTP服务器的TCP端口号都是21,每个Telnet服务器的TCP端口号都是23,每个TFTP(简单文件传送协议)服务器的UDP端口号都是69。

字节序
概述
字节序是指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序。
常见序
1. Little endian:将低序字节存储在起始地址
2. Big endian:将高序字节存储在起始地址
Little endian 小端字节序
Big endian 大端字节序

网络字节序=大端字节序
在这里插入图片描述

字节序转换api

#include <netinet/in.h>
uint16_t htons(uint16_t host16bitvalue);    //返回网络字节序的值uint32_t htonl(uint32_t host32bitvalue);    //返回网络字节序的值uint16_t ntohs(uint16_t net16bitvalue);     //返回主机字节序的值uint32_t ntohl(uint32_t net32bitvalue);     //返回主机字节序的值

h代表host,n代表net,s代表short(两个字节),l代表long(4个字节),通过上面的4个函数可以实现主机字节序和网络字节序之间的转换。有时可以用INADDR_ANY,INADDR_ANY指定地址让操作系统自己获取
在这里插入图片描述
在这里插入图片描述

分割线===============================================

步骤:

一、指定讲“汉语”(连接协议)

在这里插入图片描述

int socket(int domain, int type, int protocol);

1.domain:
指明所使用的办议族,通常为AF_ INET,表示互联网协议族( TCP/IP协议族) ;
●AF INET IPv4因特网域
◆Ar_INETS IPv6因特网城
◆AF UNIX Unix域
●Al ROUIE 路山套接字
●AF_KEY密钥套接字
●AF
UMPSPEC 未指定

2.type参数指定socket的光型:
●SOCK_STREAM:
流式会接字提供可靠的、面问连按的通信流;它使用TCP协议,从而呆证了数据传愉的正确性私顺字性
●SOCK_DGRAM
数据报会接子定义了种无连接的服 。数据通过相互独立的振义进行传愉,是无序的,并且不得证是可靠、无差错的。它使用数据报协议LDP。
●SOCK_RAW
允许程序使用低层协议,原始自孩字允计对底层协议如IP成ICNP进行直按访问,边能很大但使用领为不便,主要用丁一些办议的开发。

3.protocol
通常赋信”0”。
●0选择type类型对应的国认协议
●IPPROTO_TCP TCP传销协议
●IPPROTO_UDP UDP 传轴办议
●IPPROTO_SCTP SCTP传偷协议
●IPPROTO_TIPC TIPC传输协议

二、地址准备好

在这里插入图片描述
bind()函数: IP号端口号与相应描述字赋值函数

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

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

功能
●用于绑定IP地址和端口号到socketfd

参数
●sockfd
是一个socket描述符
●addr
是一个指向包含有本机IP地址及端口号等信息的sockaddr类型的指针,指向要绑定给sockfd的协议地址结构,这个地址结构根据地址创建socket时的地址协议族的不同而不同
在这里插入图片描述
地址转换API
int inet_aton(const char* straddr,struct in_addr *addrp);
把字符串形式的“192.168.1.123”转为网络能识别的格式

char* inet_ntoa(struct in_addr inaddr);
把网络格式的ip地址转为字符串形式

三、监听

在这里插入图片描述

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

int listen(int sockfd, int backlog);

功能

●设置能处理的最大连接数,listen()并未开始接受连线,只是设置sockect的listen模式, listen函数只用于服务器端,服务器进程不知道要与谁连接,因此,它不会主动地要求与某个进程连接,只是一直监听是否有其他客户进程与之连接, 然后响应该连接请求,并对它做出处理,一个服务进程可以同时处理多个客户进程的连接。主要就两个功能:将一个未连接的套接字转换为一个被动套接字(监听) ,规定内核为相应套接字排队的最大连接数。
●内核为任何一个给定监听套接字维护两个队列:
●未完成连接队列,每个这样的SYN报文段对应其中-项:已由某个客户端发出并到达服务器,而服务器正在等待完成相应的TCP三次握手过程。这些套接字处于SYN_ REVD 状态;
●已完成连接队列,每个已完成TCP三次握手过程的客户端对应其中-项。这些套接字处于ESTABLISHED 状态;

参数
●sockfd
sockfd是socket系统调用返回的服务器端socket描述符
●. backlog
backlog指定在请求队列中允许的最大请求数

四、 连接

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

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

功能
●accept 函数由TCP服务器调用, 用于从已完成连接队列队头返回下一 个已完成连接。如果已完成连接队列为空, 那么进程被投入睡眠。

参数
●sockfd
sockfd是socket系统调用返回的服务器端socket描述符
●addr
用来返回已连接的对端(客户端)的协议地址
● addrled
客户端地址长度

返回值
●该函数的返回值是一个 新的套接字描述符,返回值是表示已连接的套接字描述符,而第一个 参数是服务器监听套接字描述符。一个服务 器通常仅仅创建一个监听套接字, 它在该服务器的生命周期内一直存在。内核为每个由服务器进程接受的客户连接创建一个已连接套接字(表示 TCP三次握手已完成),当服务器完成对某个给定客户的服务时,相应的已连接套接字就会被关闭。

数据收发

在这里插入图片描述
数据收发常用第二套API
在这里插入图片描述

客户端的connect函数

在这里插入图片描述

以上是关于Linux系统编程—网络编程—socket编程步骤的主要内容,如果未能解决你的问题,请参考以下文章

Linux网络编程(Socket)

Linux(程序设计):42---UDP网络编程(单播)

linux socket编程系统调用栈

linux系统socket通信编程1

Linux操作系统 - 网络编程socket

linux系统UDP的socket通信编程2