socket编程-TCP各函数及其用法

12 篇文章 0 订阅
订阅专栏
本文介绍了socket编程中的TCP流套接字和数据报套接字,包括它们的特点和应用场景。详细讲解了socket创建、地址结构、端口转换函数以及bind、listen、accept、send和recv等关键函数的使用,同时提供了客户端和服务端的简单代码示例。
摘要由CSDN通过智能技术生成

socket编程-TCP


socket主要类型

流套接字(SOCK_STREAM)

流套接字用于提供面向连接、可靠的数据传输服务。该服务将保证数据能够实现无差错、无重复送,并按顺序接收。流套接字之所以能够实现可靠的数据服务,原因在于其使用了传输控制协议,即TCP协议。

数据报套接字(SOCK_DGRAM)

数据报套接字提供一种无连接的服务。该服务并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据报套接字使用UDP协议进行数据的传输。由于数据报套接字不能保证数据传输的可靠性,对于有可能出现的数据丢失情况,需要在应用层中做相应的处理。

原始套接字(SOCK_RAW)

原始套接字与标准套接字(标准套接字指的是前面介绍的流套接字和数据报套接字)的区别在于:原始套接字可以读写内核没有处理的IP数据包,而流套接字只能读取TCP协议的数据,数据报套接字只能读取UDP协议的数据。因此,如果要访问其他协议发送的数据必须使用原始套接。

实际应用中,数据报socket的应用场景比较少

流套接字(SOCK_STREAM)流程图

在这里插入图片描述

socket函数:socket函数用于创建一个新的socket,也就是向系统申请一个socket资源,socket函数用户客户端和服务端。socket()函数的返回值其本质是一个文件描述符,是一个整数。一般情况下,socket创建都会成功,除非系统资源耗尽,socket函数一般不会返回失败(-1)。其函数声明如下:

int socket(int domain, int type, int protocol);
  1. domain
     协议域,又称协议族(family)。常用的协议族有AF_INET、AF_INET6、AF_LOCAL(或称AF_UNIX,Unix域Socket)、AF_ROUTE等。协议族决定了socket的地址类型,在通信中必须采用对应的地址 ,如AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合、AF_UNIX决定了要用一个绝对路径名作为地址。

  2. type
     指定socket类型。常用的socket类型有SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等。流式socket(SOCK_STREAM)是一种面向连接的socket,针对于面向连接的TCP服务应用。数据报式socket(SOCK_DGRAM)是一种无连接的socket,对应于无连接的UDP服务应用。

  3. protocol
     指定协议。常用协议有IPPROTO_TCP、IPPROTO_UDP、IPPROTO_STCP、IPPROTO_TIPC等,分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。

    示例代码如下:

	//1.创建套接字
    int ServerSockFd;
    if((ServerSockFd=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))==-1)//socket创建失败
    {
        perror("socket 创建失败");
        return -1;
    }

sockaddr结构体与sockaddr_in结构体:

sockaddr在头文件#include <sys/socket.h>中定义,sockaddr的缺陷是:sa_data把目标地址和端口信息混在一起了,如下:

struct sockaddr {  
     sa_family_t sin_family;//地址族
    char sa_data[14]; //14字节,包含套接字中的目标地址和端口信息               
   };

sockaddr_in在头文件#include<netinet/in.h>或#include <arpa/inet.h>中定义,该结构体解决了sockaddr的缺陷,把port和addr 分开储存在两个变量中,如下:

/* Structure describing an Internet socket address.  */
struct sockaddr_in
  {
    __SOCKADDR_COMMON (sin_);
    in_port_t sin_port;			/* Port number.  */
    struct in_addr sin_addr;		/* Internet address.  */
 
    /* Pad to size of `struct sockaddr'.  */
    unsigned char sin_zero[sizeof (struct sockaddr)
			   - __SOCKADDR_COMMON_SIZE
			   - sizeof (in_port_t)
			   - sizeof (struct in_addr)];
  };
  1. 二者长度一样,都是16个字节,即占用的内存大小是一致的,因此可以互相转化。二者是并列结构,指向sockaddr_in结构的指针也可以指向sockaddr。
  2. sockaddr常用于bind、connect、recvfrom、sendto等函数的参数,指明地址信息,是一种通用的套接字地址。
  3. sockaddr_in 是internet环境下套接字的地址形式。所以在网络编程中我们会对sockaddr_in结构体进行操作,使用sockaddr_in来建立所需的信息,最后使用类型转化就可以了。一般先把sockaddr_in变量赋值后,强制类型转换后传入用sockaddr做参数的函数:sockaddr_in用于socket定义和赋值;sockaddr用于函数参数。

两个函数 htons() 和 inet_addr()。

  1. htons()作用是将端口号由主机字节序转换为网络字节序的整数值。(host to net)
  2. inet_addr()作用是将一个IP字符串转化为一个网络字节序的整数值,用于sockaddr_in.sin_addr.s_addr。
  3. inet_ntoa()作用是将一个sin_addr结构体输出成IP字符串(network to ascii)。
  4. htonl()将u_long从主机转换为 TCP/IP 网络字节顺序 (,这是大端)
  5. 已服务端为例进行演示
	//2.进行绑定,指定用于通信的ip地址和端口
    struct sockaddr_in ServerAddr;//服务端地址信息数据结构
    //将协议簇指定为ipv4
    ServerAddr.sin_family=AF_INET;
    //服务端程序绑定本主机的任意IP地址
    ServerAddr.sin_addr.s_addr=htonl(INADDR_ANY);
    服务端程序绑定指定ip
    //ServerAddr.sin_addr.s_addr=inet_addr("127.0.0.1");
    ServerAddr.sin_port=htons(9000);

bind函数:服务端把用于通信的地址和端口绑定到socket上。如果绑定的地址错误,或端口已被占用,bind函数一定会报错,否则一般不会返回错误。如无错误发生,则bind()返回0。否则的话,将返回-1。其函数声明如下:

int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
  1. 参数sockfd,需要绑定的socket,是一个文件描述符。
  2. 参数addr,存放了服务端用于通信的地址和端口,用结构体sockaddr_in强制转换得到。
  3. 参数addrlen,表示addr结构体的大小。
  4. 返回值:成功则返回0,失败返回-1,错误原因存于errno 中。

    示例代码如下:
	if(bind(ServerSockFd,(sockaddr*)&ServerAddr,sizeof(ServerAddr))!=0)
    {
        perror("bind failed");
        close(ServerSockFd);
        return -1;
    }

listen函数把主动连接socket变为被动连接的socket,使得这个socket可以接受其它socket的连接请求,从而成为一个服务端的socket。//返回:0-成功, -1-失败 listen函数一般不会返回错误。其函数声明如下:

int listen(int sockfd, int backlog);
  1. 参数sockfd,已经被bind过的socket。
     socket函数返回的socket是一个主动连接的socket,在服务端的编程中,程序员希望这个socket可以接受外来的连接请求,也就是被动等待客户端来连接。需要通过某种方式来告诉系统当前的socket是可连接的,则可以通过调用listen函数来完成这件事。

  2. 参数backlog,这个参数涉及请求队列的大小。
     当套接字正在处理客户端请求时,如果有新的请求进来,套接字是没办法处理的,只能把请求放进缓冲区,等待当前请求结束后,再从缓冲区中读取出来进行处理。如果不断有新的请求进来,按照先后顺序在缓冲区排队,直到缓冲区满,这个缓冲区就称为请求队列。

  3. 当调用listen之后,服务端的socket就可以调用accept来接受客户端的连接请求。

示例代码如下:

	//3.将socket设置为监听模式 listen成功返回0,失败返回-1
    if(listen(ServerSockFd, 5))
    {
        perror("listen failed");
        close(ServerSockFd);
        return -1;
    }

accept函数等待客户端的连接,如果没有客户端连上来,它就一直等待,这种方式称之为阻塞。accept等待到客户端的连接后,创建一个新的socket,函数返回值就是这个新的socket,服务端使用这个新的socket和客户端进行报文的收发。accept在等待的过程中,如果被中断或其它的原因,函数返回-1,表示失败,如果失败,可以重新accept。

// 返回值:成功则返回0,失败返回-1,错误原因存于errno 中。
// accept在等待的过程中,如果被中断或其它的原因,函数返回-1,表示失败,如果失败,可以重新accept。
int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen);
  1. 参数sockfd是已经被listen过的socket。
  2. 参数addr用于存放客户端的地址信息,用sockaddr结构体表达,如果不需要客户端的地址,可以填0。
  3. 参数addrlen用于存放addr参数的长度,如果addr为0,addrlen也填0。

示例代码如下:

	//4.接收客户端的请求
    int ClientSockFd;
    struct sockaddr_in ClientAddr;
    int len=sizeof(ClientAddr);
    if((ClientSockFd=accept(ServerSockFd, (sockaddr*)&ClientAddr, (socklen_t*)&len))==-1)
    {
        perror("accept failed");
        close(ServerSockFd);
        close(ClientSockFd);
        return -1;
    }

send函数用于把数据通过socket发送给对端。不论是客户端还是服务端,应用程序都用send函数来向TCP连接的另一端发送数据。

// 函数返回已发送的字符数。出错时返回-1,错误信息errno被标记
// 如果send函数返回的错误(<=0),表示通信链路已不可用。
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
  1. sockfd:已建立好连接的socket。
  2. buf:需要发送的数据的内存地址,可以是C语言基本数据类型变量的地址,也可以数组、结构体、字符串,内存中有什么就发送什么。
  3. len:需要发送的数据的长度,为buf中有效数据的长度。
  4. flags填0, 其他数值意义不大。

示例代码如下:

		if((ret=send(ClientSockFd,sen,sizeof(sen),0))==-1)
        {
            std::cout<<"send ret="<<ret<<std::endl;
            break;
        }
        std::cout<<"服务端发送:"<<rec<<std::endl;
        std::cout<<"send ret="<<ret<<std::endl;

recv函数用于接收对端通过socket发送过来的数据。不论是客户端还是服务端,应用程序都用recv函数接收来自TCP连接的另一端发送过来数据。

// 函数返回已接收的字符数。出错时返回-1,失败时不会设置errno的值。
// 如果recv函数返回的错误(<=0),表示通信通道已不可用。
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
  1. sockfd:已建立好连接的socket。
  2. buf:用于接收数据的内存地址,可以是C语言基本数据类型变量的地址,也可以数组、结构体、字符串,只要是一块内存就行了。
  3. len:需要接收数据的长度,不能超过buf的大小,否则内存溢出。
  4. flags填0, 其他数值意义不大。

示例代码如下:

		//recv接收函数,失败返回-1
        if((ret=recv(ClientSockFd,rec,sizeof(rec),0))==-1)
        {
            std::cout<<"recv ret="<<ret<<std::endl;
            break;
        }

        std::cout<<"服务端接收:"<<rec<<std::endl;
        std::cout<<"recv ret="<<ret<<std::endl;

connect函数用于将参数sockfd 的socket 连至参数serv_addr 指定的服务端,参数addrlen为sockaddr的结构长度。返回值:成功则返回0,失败返回-1,错误原因存于errno 中。connect函数只用于客户端,,如果服务端的地址错了,或端口错了,或服务端没有启动,connect一定会失败。

int connect(int sockfd, struct sockaddr * serv_addr, int addrlen);
  1. sockfd:标识未连接套接字的描述符。
  2. serv_addr:指向应建立连接的 sockaddr 结构的指针。
  3. addrlen:名称参数指向的 sockaddr 结构的长度(以字节为单位)

示例代码如下:

	//申请服务端地址信息数据结构 因为要与服务端进行相连
    struct sockaddr_in ServerAddr;
    //绑定端口和地址
    ServerAddr.sin_family=AF_INET;//ipv4
    ServerAddr.sin_port=htons(9000);
    ServerAddr.sin_addr.s_addr=inet_addr("127.0.0.1");

    //2.连接套接字
    if(connect(ClientSockFd, (sockaddr*)&ServerAddr, sizeof(ServerAddr))==-1)
    {
        perror("connect failed");
        return -1;
    }
    std::cout<<"客户端连接成功"<<std::endl;

最后完整简易服务端代码:https://blog.csdn.net/weixin_45256307/article/details/129417531

最后完整简易客户端代码:https://blog.csdn.net/weixin_45256307/article/details/129417589

TCP函数
Little devil
11-07 1035
1、socket() 函数的作用:创建一个socket()套接字 函数的头文件:#include 函数的原型:int socket(int domain, int type, int protocol); 函数的参数:          Domain:表示使用何种地址类型                  AF_INET:IPV4网络络协议
TCP 函数
weixin_33849942的博客
06-21 171
[root@localhost tt]# man listen LISTEN(2) Linux Programmer’s Manual LISTEN(2) NAME listen - listen for connections on a socket SYNOPSIS #inc...
Socket编程 (连接,发送消息) (TcpUdp) - Part1
最新发布
ForKnowledgeMe的博客
09-06 861
Tcp协议相对通讯来说相对可靠,信息不易丢失,Tcp协议发送消息,发送失败时会重复发送消息等原因。所以对于要求通讯安全较高的程序来说,选择Tcp协议的通讯相对合适。Upd协议通讯个人是比较推荐的,占用资源小,低延时,响应速度快。至于可靠性是可以通过一些应用层加以封装控制得到相应的满足。
TCP 通信中的一些函数
潜心习安全
03-04 1836
基于 C 的 1.socket 函数 int socket(int domain,int type,int protocol) 描述:用于创建通信的套接字,并返回该套接字的文件描述符。 domain:网络程序所在主机采用的通信协议。(AF_UNIX、AF_INET) type:指定套接字类型。 protocol:指定套接字所使用的通信协议。 2.bind 函数 int...
socket(AF_INET, SOCK_STREAM, IPPROTO_IP);//创建TCPsocket
热门推荐
种田能手
10-28 1万+
/* *创建TCPsocket */SOCKET        sListen,    sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);    if (sListen == SOCKET_ERROR)    {        printf("socket() failed: %d/n", WSAGetLastError());        r
tcp通信函数
07-04
基于c语言编写的tcp通信程序,客户端建立,数据发送,测试程序
linux_socket网络套接字函数(TCP通信)-socket函数-bind函数-listen函数-accept函数-connect函数-send函数-recv函数
qq_44177918的博客
05-07 1706
socket函数 bind函数 listen函数 accept函数 connect函数 send函数 recv函数 首先将整个结构体清零,然后设置地址类型为AF_INET,网络地址为INADDR_ANY,这个宏表示本地的任意IP地址,因为服务器可能有多个网卡,每个网卡也可能绑定多个IP地址,这样设置可以在所有的IP地址上监听,直到与某个客户端建立了连接时才确定下来到底用哪个IP地址,端口号为6666。客户端需要调用connect()连接服务器,connect和bind的参数形式一致,区别在于bind的参数是
TCP函数2
Little devil
11-10 241
8、  大端模式、小端模式 大端模式:低字节放在低地址,高字节放在高地址 小端模式:低字节放在高地址,高字节放在低地址 字节序的转化函数 头文件:#include 从主机发送到网络:uint32_t  htonl(uint32_t  hostin32);//32位数据传送,从主机到网络                   uint16_t  htonl(uin
Socket编程-tcp&udp-测试用例.docx
06-28
Socket编程在IT领域中是网络通信的基础,尤其在OpenWrt软路由的自定义Web界面开发中扮演着重要角色。OpenWrt是一个轻量级的Linux发行版,常用于路由器和其他嵌入式设备。Luci是OpenWrt的Web管理界面,通过luci组件和...
Modbus-Tcp采用Socket与NModbus两种方式
10-15
标题中的“Modbus-Tcp采用Socket与NModbus两种方式”指的是在实现基于Modbus-TCP协议的通信时,采用了两种不同的技术手段:Socket编程和使用NModbus库。这两种方法都是为了与支持Modbus-TCP协议的设备进行数据交换。...
tcp_socket.rar_TCP socket_socket_socket tcp_socket-tcp
09-23
以上就是关于TCP套接字的基本概念和使用方法。理解这些知识后,你就能编写出简单的TCP通信程序,为更复杂的网络应用打下基础。在实际项目中,还需要考虑错误处理、异常捕获、性能优化等因素,以实现更加健壮和高效的...
利用socket套接字发送tcp数据包
08-03
填充一个TCP数据包,并发送给目的主机。 1. 以命令行形式运行:SendTCP source_ip source_port dest_ip dest_port。 2. 头部参数自行设定,数据字段为“This is my homework of network of network,I am happy!”
C语言SOCKET编程--超级完整.doc
07-19
### C语言SOCKET编程知识点详解 #### 一、Socket编程概览 - **定义与概念**: - **Socket**(套接字)是一种用于进程间通信的机制,允许一个程序通过网络与其他程序进行交流。 - 在Unix系统中,一切皆视为文件,...
Java TCP-IP Socket编程-卡尔弗特.pdf
10-25
Java TCP/IP Socket编程网络通信领域中的核心技术,尤其在Java编程中,Socket是实现客户端与服务器之间通信的基础。本资料“Java TCP-IP Socket编程-卡尔弗特.pdf”旨在深入探讨如何利用Java语言进行TCP/IP套接字...
网络编程】TCP有关函数
zjq_smile的博客
11-07 516
1、socket函数 原型:int socket(int family, int type, int protocol); 作用:建立一下新的socket套接字 参数:family:表示使用的是何种地址类型;AF_INET,IPV4;AF_INET6,IPV6;            类型:SOCK_STREAM 用于TCP                       SOCK_DGRA
TCP通信相关函数
jun8086的博客
10-17 1057
【代码】TCP通信相关函数。socket()\bind()\connect()\
网络通信2:TCP函数
adlics_r的博客
11-07 332
1.Inet_addr()函数 函数作用: 十进制转换成二进制 函数原型: int inet_addr(const char *strptr); 参数: Strptr:要转换的IP地址字符串 返回值: 成功:32位二进制IP地址(网络字节序) 出错:-12.Inet_pton函数 函数原型: int inet_pton(int family, co
Socket实现简单文件传输(TCP
Mudrock__的博客
10-17 1412
3.调用socket.shutdownInput或socket.shutdownOutput后,inputStream或outputStream被禁用,但socket不会被关闭。1.调用socket.close后无需再关闭通过socket创建的inputSteam或outputStream。2.调用inputSteam.close或outputStream.close后,socket也会被关闭。
read函数_第五十一章、TCP连接之发送(read函数)和接收(write函数
weixin_39798579的博客
12-07 2096
这一章我们来学习下read和write这两个函数。进过前几章的学习我们已经将客户端和服务器端连接上了,那么我们还需要让两端进行数据交流,那它们怎么交流呢?这就需要我们今天学习的read和write函数了。read和write函数是从套接字读和写数据,我们来看下它们的定义:ssize_t read (int __fd, void *__buf, size_t __nbytes)ssize_t wri...
写文章

热门文章

  • DBeaver连接阿里云mysql步骤 3019
  • socket编程-UDP各函数及其用法 2103
  • socket编程-TCP各函数及其用法 1786
  • Tomcat手动部署动态Web项目(详细步骤) 1732
  • 73. 矩阵置零 1331

分类专栏

  • leetcode 605篇
  • 网络编程 12篇
  • 习题 146篇
  • 算法 9篇
  • 实用 4篇

最新评论

  • 1096 大美数

    咔咔咔的: 已修改,谢谢指正

  • 1096 大美数

    灰末: 第18行错了

  • Linux下网络编程-简易poll服务器和客户端

    ha_lydms: 优质好文支持支持,优质好文支持支持

  • VS2022创建MFC项目,菜单控件设置事件处理程序出现没有消息类型的情况

    卡蛙伊: 更换整个生成工具的版本,重新构建整个项目就可以了,我是从v143降到v141,删除项目再重新创建了一个就成功了,虽然双击button还是不能直接转到处理函数

  • VS2022创建MFC项目,菜单控件设置事件处理程序出现没有消息类型的情况

    咔咔咔的: 打开软件提示我有更新,就跟着更新了

最新文章

  • 2306. 公司命名
  • 2207. 字符串中最多数目的子序列
  • 1014. 最佳观光组合
2024
10月 14篇
09月 22篇
08月 40篇
07月 73篇
06月 69篇
05月 71篇
04月 41篇
03月 51篇
02月 70篇
01月 126篇
2023年189篇
2022年5篇
2021年3篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值

玻璃钢生产厂家临沂玻璃钢雕塑设计黑龙江玻璃钢雕塑工程施工江苏定制玻璃钢雕塑服务介绍梅河口玻璃钢雕塑张掖玻璃钢植物雕塑公司湖南玻璃钢瓜果雕塑运城玻璃钢人物雕塑生产厂家授权品牌 商场美陈名图玻璃钢雕塑款式多梅州玻璃钢人物雕塑生产厂家陕西动物玻璃钢雕塑供应商玻璃钢雕塑更好贵阳玻璃钢仿生雕塑商场女神节美陈延津玻璃钢雕塑设计宜春景观玻璃钢雕塑批发北京季节性商场美陈多少钱青岛市玻璃钢人物雕塑生产商黄山玻璃钢卡通人物雕塑上海走廊商场美陈怎么样新乡佛像玻璃钢雕塑金昌广场玻璃钢雕塑定制成立商场美陈策划部天鹅雕塑玻璃钢常德玻璃钢雕塑设计厂家推荐湖南玻璃钢景观雕塑生产商场美陈投标报价淮南雕塑玻璃钢仿铜玻璃钢雕塑造型红旗玻璃钢雕塑费用香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化