基于TCP/UDP的socket服务器搭建流程

这篇具有很好参考价值的文章主要介绍了基于TCP/UDP的socket服务器搭建流程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

TCP/UDP概念介绍

一、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、概念

字节序,就是多字节类型的数据在计算机内存中存储或者网络传输时各字节的存放顺序。是在跨平台和网络编程中,时常要考虑的问题

2、分类

字节序经常被分为两类:
1. Big-Endian(大端):高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
2.Little-Endian(小端):低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
3.网络字节序=大端字节序

样例介绍:
在内存中双字0x01020304(DWORD)的存储方式
内存地址
4000&4001&4002&4003
LE 04 03 02 01
BE 01 02 03 04

3、C程序在内存空间的映射

C程序映射中内存的空间布局大致如下:
最高内存地址 0xFFFFFFFF
栈区(从高内存地址,往 低内存地址发展。即栈底在高地址,栈顶在低地址)
堆区(从低内存地址 ,往 高内存地址发展)
全局区(常量和全局变量)
代码区
最低内存地址 0x00000000

socket服务器与客户端开发流程

一、流程介绍

基于TCP/UDP的socket服务器搭建流程
详细说明文章来源地址https://www.toymoban.com/news/detail-402565.html

  1. socket() 创建套接字
  2. bind() 为套接字添加信息(IP地址+端口号)
  3. listen() 监听网络连接(客户端接入)
  4. accept() 监听到有客户端接入,接收一个连接
  5. read/write 数据交互
  6. close() 关闭套接字,断开连接

二、socket服务器搭建API介绍

1、scoket() 创建套接字

//**创建套接字**
int socket(int domain, int type, int protocol);
 - domain:
指明所使用的协议族,通常为AF_INET,表示互联网协议族(TCP/IP协议族)- AF_INET   IPv4因特网域
 - AF_INET6  IPv6因特网域
 - AF_UNIX   Unix域
 - AF_ROUTE  路由套接字
 - AF_KEY    秘钥套接字
 - AF_UNSPEC 未指定

 - type:
 指定socket的类型:
 - SOCK_STREAM:
 流式套接字提供可靠的、面向连接的通信流;它使用TCP协议,从而保证了数据传输的正确性和顺序性
 - SOCK_DGRAM:
数据报套接字定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证是可靠、无差错的。它使用数据报协议UDP。
 - SOCK_RAW:
允许程序使用低层协议,原始套接字允许对低层协议如IP或者ICMP进行直接访问,功能强大但使用较为不便,主要用于一些协议栈的开发。

 - protocol:
通常赋值“0- 0选择type类型对应的默认协议 
 - IPPROTO_TCP   TCP传输协议 
 - IPPROTO_UDP   UDP传输协议
 - IPPROTO_SCTP  SCTP传输协议     
 - IPPROTO_SCTP  TIPC传输协议

2、bind() 将套接字与地址关联

//关联地址和套接字
#include <sys/types.h>    
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr,
        socklen_t addrlen);
功能:
	用于绑定IP地址和端口号到socketfd
参数:
 - sockfd   是一个socket描述符
 - addr     是一个指向包含有本机IP地址及端口号等信息的sockaddr类型的指针,指向要绑定给
            sockfd的协议地址结构。这个地址结构根据地址创建socket时的地址协议族的不同而不同
 - addrlen  套接字的大小

IPv4对应的是:
	struct sockaddr {
 		unsigned short sa_family;	//协议族
 		char        sa_data[14];	//IP+端口
	 }
同等替换:
	struct sockaddr_in {
 		sa_family_t     sin_family;	/*协议族*/
 		in_port_t	    sin_port;	/*端口号*/
 		struct in_addr  sin_addr;   /*IP地址结构体*/
 		unsigned char   sin_zero[8]; /*填充 没有实际意义,只是为跟sockaddr结构在内存中对齐,这样两者才能相互转换*/
	 }

3、地址转换API

1. 把字符串形式的“192.168.1.123”转为网络能识别的格式
int inet_aton(const char* straddr,struct in_addr *addrp);
功能:
	将一个字符串表示的点分十进制IP地址IP转换为网络字节序存储在addr中,并且返回该网络字节序表示的无符号整数。
参数:
	const char *straddr: 我们输入的点分十进制的IP地址
	struct in_addr* addr: 将IP转换为网络字节序(大端存储)后并保存在addr中
返回值:
	成功;返回点分十进制的IP地址对应的网络字节序表示的无符号整数
	失败;返回0
2. 把网络格式的ip地址转为字符串形式
char* inet_ntoa(struct in_addr inaddr); 
功能:
	将一个网络字节序的IP地址(也就是结构体in_addr类型变量)转化为点分十进制的IP地址(字符串)
参数:
	struct in_addr{    
		in_addr_t s_addr;
	};
	in_addr是一个按网络顺序存储的IP地址
返回值:
	该函数的返回值是一个字符串,这个字符串是点分十进制的IP地址

4、listen() 监听

//监听设置函数
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int listen(int sockfd, int backlog);
功能:
 - 设置能处理的最大连接数,listen()并未开始接收连线,只是设置socket的listen模式,listen函数只用于服务器端,服务器进程不知道要与谁连接,
   因此,它不会主动地要求与某个进程连接,只是一直监听是否有其他客户进程与之连接,然后响应该连接请求,并对它作出处理,一个服务进程可以同时处理多个客户进程的连接。
   主要就两个功能:将一个未连接的套接字转换为一个被动套接字(监听),规定内核为相应套接字排队的最大连接数。
 - 内核为任何一个给定监听套接字维护两个队列:
 	 - 未完成连接队列,每个这样的SYN报文端对应其中一项;已由某个客户端发出并到达服务器,而服务器正在等待完成相应的TCP三次握手过程。这些套接字处于SYN_REVD状态。
 	 - 已完成连接队列,每个已完成TCP三次握手过程的客户端对应其中一项。这些套接字处于ESTABLISHED状态
参数:
	- sockfd:sockfd是socket系统调用返回的服务端socket描述符
	- backlog:backlog指定在请求队列中允许的最大请求数

5、accept 连接

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:
	accept函数由TCP服务器调用,用于从已完成连接队列队头返回下一个已完成连接。如果已完成连接队列为空,那么进程进入睡眠。
参数:
	sockfd: 是socket系统调用返回的服务器端socket描述符
	addr:   用来返回已连接的对端(客户端)的协议地址
	addrled:客户端地址长度
返回值:
	该函数的返回值是一个新的套接字描述符,返回值是表示已经连接的套接字描述符,而第一个参数是服务器监听套接字描述符。
	一个服务器通常仅仅创建一个监听套接字,它在该服务器的生命周期内一直存在。
	内核为每个由服务器进程接收的客户连接创建一个已连接套接字(表示TCP三次握手已经完成),当服务器完成对某个给定客户的服务时,相应的已连接套接字就会被关闭。

6、数据收发

//字节流读取函数
在套接字通信中进行字节读取函数:read(),write().与I/O中的读取函数略有区别,因为他们输入或输出的字节数可能比请求的少。
ssize_t write(int fd, const void*buf,size_t nbytes);
ssize_t read(int fd,void *buf,size_t nbyte);
/*说明
*函数均返回读或写的字节个数,出错则返回-1
*/
第一个将buf中的nbytes个字节写入到文件描述符fd中,成功时返回写的字节数。
第二个为从fd中读取nbyte个字节到buf中,返回实际所读的字节数。详细应用说明参考使用read、write读写socket(套节字)。
网络I/O还有一些函数,例如:recv()/send(),readv()/writev(),recvmsg()/sendmsg(),recvfrom()/sendto()等。

数据收发常用第二套API
1.在TCP套接字上发送数据函数:有连接
ssize_t send(int s,const void *msg,size_t len,int flags);
//包含3要素:套接字s,待发数据msg,数据长度len
//函数只能对处于连接状态的套接字使用,参数s为已建立好连接的套接字描述符,即accept函数的返回值
//参数msg指向存放待发送数据的缓冲区
//参数len为待发送数据的长度,参数flags为控制选项,一般设置为0
2.在TCP套接字上接收数据函数:有连接
ssize_t recv(int s,void *buf,size_t len,int flags);
//包含3要素:套接字s,待发数据msg,数据长度len
//函数recv从参数s所指定的套接描述符(必须是面向连接的套接字)上接收
//数据并保存到参数buf所指定的缓冲区
//参数len则为缓冲区长度,参数flags为控制选项,一般设置为0

7、connect()

//客户机连接主机
#include <sys/types.h>      
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr,
                   socklen_t addrlen);
功能:
	该函数用于绑定之后的client端(客户端),与服务器建立连接
参数:
sockfd:是目的服务器的socket描述符
addr:是服务器端的IP地址和端口号的地址结构指针
addrlen:地址长度常设置为sizeof(struct sockaddr)
返回值:
成功返回0,遇到错误时返回-1,并且errno中包含相应的错误码

到了这里,关于基于TCP/UDP的socket服务器搭建流程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C#上位机基础学习_基于SOCKET实现与PLC服务器的TCP通信(一)

    测试软件: TIA PORTAL V15.1 S7-PLCSIM ADVANCED V3.0 Visual Studio 2019 如下图所示,打开S7-PLCSIM ADVANCED V3.0仿真软件,新键一个实例,设置仿真PLC的IP地址等参数,然后点击Start激活PLC, 如下图所示,激活PLC后,可以看到已经存在一个实例, 如下图所示,打开TIA PORTAL V15.1,新建一个项目,

    2023年04月15日
    浏览(45)
  • 《TCP/IP网络编程》阅读笔记--基于UDP的服务器端/客户端

    目录 1--TCP和UDP的主要区别 2--基于 UDP 的数据 I/O 函数 3--基于 UDP 的回声服务器端/客户端 4--UDP客户端Socket的地址分配 5--UDP存在数据边界 6--UDP已连接与未连接的设置 ① TCP 提供的是可靠数据传输服务,而 UDP 提供的是不可靠数据传输服务; ② UDP 在结构上比 TCP 更简洁,其不会

    2024年02月09日
    浏览(61)
  • 基于c++的简易web服务器搭建(初尝socket编程)

    用 Socket 编程实现一个 Web 服务器(端口号 8080) 实验要求: 该 Web 服务器在一台主机上运行,支持多台主机同时访问 有服务控制界面,开启和关闭按钮 能够指定主页(index.html) 测试方法: 在同组其他主机上,打开浏览器,输入 http://主机 IP 地址:8080,浏览器上显示主页

    2023年04月08日
    浏览(44)
  • 【python】TCP socket服务器 Demo

    目录 一、单线程服务器 二、多线程服务器 三、多线程服务器(发送和接收分离) 说明:只能连接一个客户端 客户端测试结果: 服务端测试结果:  说明:可以支持连接多个客户端 客户端测试结果:  服务端测试结果: 说明: 可以支持连接多个客户端,并且能够做到和多

    2024年02月09日
    浏览(38)
  • 【网络原理】使用Java基于TCP搭建简单客户端与服务器通信

    TCP服务器与客户端的搭建需要借助以下API ServerSocket 是创建TCP服务端Socket的API。 ServerSocket 构造方法 : 方法签名 方法说明 ServerSocket(int port) 创建一个服务端流套接字Socket,并绑定到指定端口 ServerSocket 方法: 方法签名 方法说明 Socket accept() 开始监听指定端口(创建时绑定的端

    2024年03月12日
    浏览(80)
  • 云服务器:开放TCP、UDP端口

            众所周知,电脑设备有些端口默认是不开放的,我们使用TCP或者UDP去连接没有开放端口时就会被防火墙拦截,所以就需要到电脑防火墙设置里面把需要用到的端口开放出来。操作如下:         1.打开防火墙(可以直接搜索)         2.新建规则       

    2024年02月03日
    浏览(54)
  • 使用Socket实现TCP版的回显服务器

    Socket(Java套接字)是Java编程语言提供的一组类和接口,用于实现网络通信。它基于Socket编程接口,提供了一种简单而强大的方式来实现网络应用程序。 Socket类库提供了丰富的方法和功能,用于处理网络通信的各个方面。它支持TCP和UDP协议,可以实现可靠的、面向连接的通信

    2024年02月14日
    浏览(47)
  • Linux网络编程:socket、客户端服务器端使用socket通信(TCP)

    socket(套接字),用于网络中不同主机间进程的通信。 socket是一个伪文件,包含读缓冲区、写缓冲区。 socket必须成对出现。 socket可以建立主机进程间的通信,但需要协议(IPV4、IPV6等)、port端口、IP地址。          (1)创建流式socket套接字。                 a)此s

    2024年02月11日
    浏览(65)
  • 【网络编程】实现UDP/TCP客户端、服务器

    需要云服务器等云产品来学习Linux的同学可以移步/--腾讯云--/--阿里云--/--华为云--/官网,轻量型云服务器低至112元/年,新用户首次下单享超低折扣。   目录 一、UDP 1、Linux客户端、服务器 1.1udpServer.hpp 1.2udpServer.cc 1.3udpClient.hpp 1.4udpClient.cc 1.5onlineUser.hpp 2、Windows客户端 二、T

    2024年02月06日
    浏览(61)
  • Socket网络编程(TCP/IP)实现服务器/客户端通信。

    一.前言 回顾之前进程间通信(无名管道,有名管道,消息队列,共享内存,信号,信号量),都是在同一主机由内核来完成的通信。 那不同主机间该怎么通信呢? 可以使用Socket编程来实现。 Socket编程可以通过网络来实现实现不同主机之间的通讯。 二.Socket编程的网络模型如

    2024年02月08日
    浏览(89)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包