本篇主要内容介绍:

  1. 介绍TCP套接字基本概念
  2. 介绍TCP套接字编程流程
  3. 基本TCP套接字函数介绍

1、TCP套接字基本概念(非官方解释,个人总结)

套接字是一种网络API,提供一种进程间的通信方法,使得相同主机或者不同主机上的进程能够使用socket定义的规范进行双向的数据通信。进程之间调用套接字接口实现相互通信,套接字接口利用下层的网络通信协议功能和系统调用实现实际的通信工作(这一部分对于编程者是透明的)。

简单说,通过socket我们可以实现进程间的通信。

定义套接字的函数为:

int socket(int family, int type, int proto);    //使用socket需要引入头文件 #include <sys/socket.h>

family参数指明的协议簇确定socket使用的协议类型,常用的值有

常用socket协议类型
参数名 解释
AF_INET IPv4协议
AF_INET6 IPv6协议
AF_UNIX UNIX域协议(文件系统套接字、本地套接字)

type参数指明产生套接字的类型,常用值有

常用套接字类型
参数名 解释
SOCK_STREAM 字节流套接字接口,可实现TCP
SOCK_DGRAM 数据包套接字接口,可实现UDP
SOCK_RAW 原始套接口,允许对较低层次的协议的直接访问

*需要注意,以上两个参数并不能随意结合。

一般情况下,第三个参数直接选择默认值0即可,会根据前两个参数匹配默认的协议。

经过上面的基本介绍,应该能够发现:若要实现TCP套接字编程,将第一个参数设置为AF_INET,第二个参数设置为SOCK_STREAM,第三个参数设置为0即可,如下代码所示:

int sockfd = socket(AF_INET, SOCK_STREAM, 0);

2、TCP套接字编程流程

TCP套接字分为服务器端和客户端,双方的编程内容有些许差异,基本的逻辑流程图如下图所示:

TCP套接字编程过程中,服务器端的流程如下:

  1. 使用socket()函数创建套接字;
  2. 将创建的套接字绑定到指定的地址结构(常常使用sockaddr_in结构体,后面会介绍);
  3. listen()函数设置套接字监听,开启服务器;
  4. 服务器处于阻塞状态,直到接收到客户端的连接请求,若有连接请求则建立连接;
  5. 接收、应答用户的请求;
  6. 关闭本连接,继续监听。

客户端的流程为:

  1. 使用socket()创建套接字;
  2. 使用connect()函数建立一个与TCP服务器的连接;
  3. 发送数据,等服务器应答之后接收数据;
  4. 断开连接。

3、基本TCP套接字函数介绍

由第二部分的流程图可以总结常用的基本套接字编程函数依次为:

3.1 socket()函数

不论是客户端还是服务器端都必须首先调用socket函数,生成一个TCP套接字。函数如下:

int socket(int family, int type, int proto); 

socket函数的参数在第一部分已经介绍过了,此处不详细介绍。特别说明一下返回值,正常情况下返回值为不等于-1的整数,作为独一无二的socket的描述符,如果调用失败 就返回INVALID_SOCKET(Linux下失败返回-1)。

3.2 bind()函数

绑定函数的作用是为前面的socket()函数产生的套接字分配一个本地协议地址,建立地址与套接字的对应关系,在实际的应用中通过bind()函数绑定的端口号来保证地址的唯一性。

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

参数sockfd是套接字返回的套接字描述符; addr是指向特定于协议的地址结构的指针,指定用于通信的本地协议地址;addrlen指定套接字地址的长度(即第二个参数结构体的长度);

如果成功调用函数则返回0, 出错返回-1;

对于每种套接字类型都有其对应的地址结构,AF_INET的地址结构由sockaddr_in定义,其基本成员有:

struct sockaddr_in {short int sin_family;         // AF_INETunsigned short int sin_port;  // 端口号struct in_addr  sin_addr;     // IP地址
};

目前为止对一个套接字编程的示例代码为:

*如果我们没特别为套接字绑定IP地址,操作系统会为我们选择一个机器IP地址,这时sin_addr使用地址0.0.0.0,使用INADDR_ANY来表示这个地址常量。

#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>int main(int argc, char **argv)
{// 创建套接字int fd = socket(AF_INET, SOCK_STREAM, 0);if (fd < 0) {perror("cannot create socket");return 0;}printf("created socket, fd: %d\n", fd);// 命名套接字struct sockaddr_in myaddr;memset(&myaddr, 0, sizeof(myaddr));myaddr.sin_family = AF_INET;myaddr.sin_addr.s_addr = htonl(INADDR_ANY);myaddr.sin_port = htons(6240);if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {perror("bind failed");return 0;}printf("bind complete, port number: %d\n", ntohs(myaddr.sin_port));exit(0);
}

(代码转自https://blog.csdn.net/lihao21/article/details/64624796?locationNum=7&fps=1)

3.3 listen()函数

listen()函数是服务器端需要使用的函数,对于所有TCP服务器,在绑定操作之后需要调用liste()函数,使他处在监听模式下。

int listen(int sockfd, int backlog); 

第一个参数是设置描述符,同前面的函数。第二个参数规定了请求队列中的最大连接数。如果一个服务器请求到来时,输入队列已经满了,该服务器套接字将拒绝连接请求。一般的第二个参数设置为5或者20.

3.4 accept()函数

该函数使得服务器接收客户端的连接请求,将完成队列中的队头条目返回给进程,并产生一个新的套接字描述符,这个新生成的套接字称为“已连接的套接字”。当已完成队列为空时,进程进入睡眠(阻塞),直到新的连接到达。

int accept(int listenfd, struct sockaddr *client, size_t addrlen); 

第一个参数是由socket()函数产生的套接字描述符,在调用accept()函数前,已经调用了listen()函数将此套接字变成了监听套接字,;第二个和第三个参数是用来返回连接对方的套接字地址结构和对应的结构长度。

函数调用成功之后返回的值是已连接套接字描述符(内核为每个被接受的客户都创建的,不是服务器端的那个一直存在的套接字描述符)。

3.5 connect()函数

该函数用于TCP客户端,建立一个与TCP服务器的连接。

int connect(int sockfd, const struct sockaddr *addr, size_t addrlen); 

connect()函数用于激发TCP的三次握手的过程,建立与远程服务器的连接,第一个参数为在客户端创建的套接字描述符。第二个参数为指向服务器的套接字地址结构的指针(在IPv4中是sockaddr_in),第三个参数是该套接字地址结构的大小。

如果调用成功返回0,出错返回-1.

3.6 close()函数

该函数用于关闭套接字,并立即返回到进程。关闭以后的套接字描述符不能用于接收和发送数据。

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

唯一的参数是需要关闭的描述符,函数成功调用返回0,出错则返回-1.

3.7 write()和read()函数

当客户端和服务器端建立连接之后,可以进行数据传输。使用write和read函数进行数据发送和接收。

int write(int sockfd, char *buf, int buf_len);        //#include <unistd.h>
int read(int sockfd, char *buf, int buf_len);         //#include <unistd.h>

write函数中的第二个参数指用户发送信息的缓冲区,第三个参数指发送信息的缓冲区的大小,read函数同理。

这两个函数若成功执行返回的值是发送/接收的字节数,若错误则返回-1。

TCP套接字编程(C语言)相关推荐

  1. UNIX环境编程(c语言)--套接字--基本TCP套接字编程

    目录 准备知识 字节序 字节序转换函数 字节操纵函数 地址转换函数 地址结构 基本TCP套接字编程 概要 socket函数 bind函数 listen函数 accept函数 connect函数 通信函 ...

  2. 《计算机网络:自顶向下方法(原书第6版)》一2.7 TCP套接字编程

    本节书摘来华章计算机<计算机网络:自顶向下方法(原书第6版)>一书中的第2章 ,第2.7节,(美)James F.Kurose Keith W.Ross 著 陈 鸣 译 更多章节内容可以访 ...

  3. 套接字编程---2(TCP套接字编程的流程,TCP套接字编程中的接口函数,TCP套接字的实现,TCP套接字出现的问题,TCP套接字多进程版本,TCP套接字多线程版本)

    TCP模型创建流程图 TCP套接字编程中的接口 socket 函数 #include <sys/types.h> /* See NOTES */ #include <sys/sock ...

  4. tcp套接字编程模型

    1. tcp套接字编程 用下面的一张图可以清楚表示: 下面的python实现也很清晰: server: def tcplink(sock, addr):print 'Accept new connec ...

  5. 《网络编程》基本 TCP 套接字编程

    在进行套接字编程之前必须熟悉其地址结构,有关套接字的地址结构可参考文章<套接字编程简介>.基于 TCP 的套接字编程的所有客户端和服务器端都是从调用socket 开始,它返回一个套接字描述 ...

  6. 计算机网络实验4 - TCP套接字编程 - 点对点聊天 - 代码实现

    客户端 package chat;import java.io.IOException; import java.io.PrintStream; import java.net.Socket; imp ...

  7. 《UNIX网络编程 卷1:套接字联网API》学习笔记——基本TCP套接字编程

    UNIX网络编程--基本TCP套接字编程 socket 函数 connect 函数 bind 函数 listen 函数 accept 函数 fork 和 exec 函数 并发服务器 close 函数 ...

  8. Experiment 0x1:TCP套接字编程

    Experiment 0x1:TCP套接字编程 文章目录 Experiment 0x1:TCP套接字编程 0x0 说明 0x1 要求 0x2 实现 0x3 源码 1- TCP服务端源码 2- TCP客 ...

  9. TCP套接字编程实例(一)

    TCP套接字编程实例(一) TCP套接字编程第一部分我们先用单线程简单实现客户端的"发"和服务器的"收".话不多说,直接上代码. 1.Client部分: #in ...

最新文章

  1. 我是如何有效的避免测试漏测?
  2. android插件化-apkplug中以监听方式获取OSGI服务-09
  3. AliOS Things 硬件抽象层(HAL)对接系列2 — SPI driver porting
  4. boost::fusion::erase_key用法的测试程序
  5. powerbi的功能介绍_PowerBI 8月更新,这几个实用功能,你应该会用到
  6. 使用Guava对并发应用程序进行基于对象的微锁定
  7. BFS(广度优先搜索)
  8. Web服务器的配置与管理(3) 配置虚拟目录
  9. 计算机课程可在平板上做吗,老师做直播,孩子上网课,掌控线上学习就靠这个平板电脑了...
  10. mysql genlog 分析_使用mysqlsla 分析 mysql logs
  11. NLP技术在金融资管领域的落地实践
  12. 无线网络何连不到服务器,关于电脑宾馆连接不上无线网络的解决方法
  13. Mybatis遇到No constructor found in ....的解决方法
  14. linux查看ipv6 dns,云解析DNS IPv6
  15. 【CSP】201903-1 小中大
  16. MongoDB:排序超出了内存限制的104857600字节
  17. MATLAB text的“关键字”
  18. c语言实现按键精灵区域找图,区域遍历所有图片(找图,多点找色)----1个函数实现...
  19. Spring Security Web : AbstractAuthenticationTargetUrlRequestHandler
  20. C++学习 11.18.19

热门文章

  1. 艺术字(CoreIDRAW)
  2. 曼哈顿距离与切比雪夫距离的互化
  3. Redis百度网盘下载
  4. ES6总结——let、const
  5. 元编程: is_lvalue_reference<Tp>
  6. Vue项目中使用axios如何进行参数拼接
  7. 团队项目:我要当管家
  8. 解决:安装html-loder后,运行报错Error: Failed to compile with 1 error
  9. 今生,我的文字只为你写
  10. Java中接口和抽象类的区别