网络通信1—TCP程序编写步骤(参照 Ubuntu 16.04 版本)(转载)

本文主要是介绍网络通信1—TCP程序编写步骤(参照 Ubuntu 16.04 版本)(转载),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转载自:https://blog.csdn.net/wenfei11471/article/details/79478105

网络通信1—TCP程序编写步骤(参照 Ubuntu 16.04 版本)

wenfei11471 2018-03-07 22:38:48

965

收藏 4

分类专栏: Linux C 语言 文章标签: TCP Linux 网络编程

版权

Linux C 语言 专栏收录该内容

31 篇文章 0 订阅

订阅专栏

  • TCP基础模型
  1. 服务器流程
    1. step 1:创建 socke() 套接字接口并判断

listenfd = socket(AF_INET, SOCK_STREAM, 0);

if (listenfd == -1)

{perror("socket failed");return -1;}

  1. step 2:设置 IP 和 Port

memset (&seraddr, 0, sizeof(seraddr));

seraddr.sin_family = AF_INET;

seraddr.sin_port = htons(8888);

seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");

  1. step 3:绑定 IP 和 Port 并判断

ret = bind(listenfd, (struct sockaddr *)&seraddr, sizeof(seraddr));

if (ret == -1)

{perror("bind failed");return -1;}

  1. step 4:监听连接并判断

ret = listen(listenfd, 5);

if (ret == -1)

{perror("listen failed");return -1;}

  1. step 5:接受连接请求并判断

connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &addrlen);

if (connfd == -1)

{perror("accept failed");return -1;}

printf("connect sucessfully: client IP: %s, Port: %d\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));

  1. step 6:接收数据并判断

ret = recv(connfd, buf, sizeof(buf), 0);

if (ret == -1)

{perror("recv failed");return -1;}

printf("recv from client: %s\nrecv %d bytes\n", buf, ret);

  1. step 7:发送数据并判断

ret = send(connfd, buf, sizeof(buf), 0);

if (ret == -1)

{perror("send failed");return -1;}

printf("send successfully!\n");

  1. step 8:关闭连接

close(connfd);

  1. step 9:检查头文件和变量是否定义

客户端流程

  1. step 1:创建 socke() 套接字接口并判断

connfd = socket(AF_INET, SOCK_STREAM, 0);

if (connfd == -1)

{perror("socket failed");return -1;}

  1. step 2:设置服务器 IP 和 Port

memset (&seraddr, 0, sizeof(seraddr));

seraddr.sin_family = AF_INET;

seraddr.sin_port = htons(8888);

seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");

  1. step 3:发送连接请求并判断

ret = connect(connfd, (struct sockaddr *)&seraddr, sizeof(seraddr));

if (ret == -1)

{perror("connect faile");return -1;}

printf("connect sucessfully!\n");

  1. step 4:发送数据并判断

ret = send(connfd, buf, sizeof(buf), 0);

if (ret == -1)

{perror("send faile");return -1;}

printf("send successfully!");

  1. step 5:接收数据

ret = recv(connfd, buf, sizeof(buf), 0);

if (ret == -1)

{perror("recv faile");return -1;}

printf("%s\n", buf);

  1. step 6:关闭连接

close(connfd);

  1. step 7:检查头文件和变量是否定义
  • TCP 循环服务器模型
  1. 服务器流程
    1. step 1:创建 socke() 套接字接口并判断

listenfd = socket(AF_INET, SOCK_STREAM, 0);

if (listenfd == -1)

{perror("socket failed");return -1;}

  1. step 2:设置 IP 和 Port

memset (&seraddr, 0, sizeof(seraddr));

seraddr.sin_family = AF_INET;

seraddr.sin_port = htons(8888);

seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");

  1. step 3:绑定 IP 和 Port 并判断

ret = bind(listenfd, (struct sockaddr *)&seraddr, sizeof(seraddr));

if (ret == -1)

{perror("bind failed");return -1;}

  1. step 4:监听连接并判断

ret = listen(listenfd, 5);

if (ret == -1)

{perror("listen failed");return -1;}

  1. step 5:设置循环连接

while(1)

  1. step 6:接受连接请求并判断

connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &addrlen);

if (connfd == -1)

{perror("accept failed");return -1;}

printf("connect sucessfully: client IP: %s, Port: %d\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));

  1. step 7:循环接收数据,直达条件满足退出

while(1)

  1. step 8:接收数据并判断

ret = recv(connfd, buf, sizeof(buf), 0);

if (ret == -1)

{perror("recv failed");return -1;}

  1. step 9:设置跳出循环的条件

if (!strncmp("quit", buf, 4))

break;

printf("recv from client: %s\nrecv %d bytes\n", buf, ret);

  1. step 10:发送数据并判断

ret = send(connfd, buf, sizeof(buf), 0);

if (ret == -1)

{perror("send failed");return -1;}

printf("send successfully!\n");

  1. step 11:关闭连接

close(connfd);

  1. step 12:检查头文件和变量是否定义

客户端流程

  1. step 1:创建 socke() 套接字接口并判断

connfd = socket(AF_INET, SOCK_STREAM, 0);

if (connfd == -1)

{perror("socket failed");return -1;}

  1. step 2:设置服务器 IP 和 Port

memset (&seraddr, 0, sizeof(seraddr));

seraddr.sin_family = AF_INET;

seraddr.sin_port = htons(8888);

seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");

  1. step 3:发送连接请求并判断

ret = connect(connfd, (struct sockaddr *)&seraddr, sizeof(seraddr));

if (ret == -1)

{perror("connect faile");return -1;}

printf("connect sucessfully!\n");

  1. step 4:设置数据循环,并获取标准输入的数据

while (1)

{fgets(buf, sizeof(buf), stdin);

buf[strlen(buf)-1] = '\0';

...}

  1. step 5:发送数据并判断

ret = send(connfd, buf, sizeof(buf), 0);

if (ret == -1)

{perror("send faile");return -1;}

printf("send successfully!");

  1. step 6:设置退出条件

if (!strncmp("quit", buf, 4))

break;

  1. step 7:接收数据

ret = recv(connfd, buf, sizeof(buf), 0);

if (ret == -1)

{perror("recv faile");return -1;}

printf("%s\n", buf);

  1. step 8:关闭连接

close(connfd);

  1. step 9:检查头文件和变量是否定义
  • TCP 并发服务器模型
  1. 服务器流程
    1. step 1:创建 socke() 套接字接口并判断

listenfd = socket(AF_INET, SOCK_STREAM, 0);

if (listenfd == -1)

{perror("socket failed");return -1;}

  1. step 2:设置 IP 和 Port

memset (&seraddr, 0, sizeof(seraddr));

seraddr.sin_family = AF_INET;

seraddr.sin_port = htons(8888);

seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");

  1. step 3:绑定 IP 和 Port 并判断

ret = bind(listenfd, (struct sockaddr *)&seraddr, sizeof(seraddr));

if (ret == -1)

{perror("bind failed");return -1;}

  1. step 4:监听连接并判断

ret = listen(listenfd, 5);

if (ret == -1)

{perror("listen failed");return -1;}

  1. step 5:设置信号处理防止僵尸进程

signal(SIGCHLD, SIG_IGN);

  1. step 6:设置循环建立连接

while(1)

  1. step 7:接受连接请求并判断

connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &addrlen);

if (connfd == -1)

{perror("accept failed");return -1;}

printf("connect sucessfully: client IP: %s, Port: %d\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));

  1. step 8:创建子进程并判断

pid = fork();

if (pid == -1)

{perror("fork create");return -1}

  1. step 9:设置父进程关闭连接并重新建立链接

if (pid > 0)

{close(connfd);continue;}

  1. step 10:子进程关闭监听,并循环接收数据

close(listenfd);

while(1)

  1. step 11:接收数据并判断

ret = recv(connfd, buf, sizeof(buf), 0);

if (ret == -1)

{perror("recv failed");return -1;}

  1. step 12:设置跳出循环的条件

if (!strncmp("quit", buf, 4))

break;

printf("recv from client: %s\nrecv %d bytes\n", buf, ret);

  1. step 10:发送数据并判断

ret = send(connfd, buf, sizeof(buf), 0);

if (ret == -1)

{perror("send failed");return -1;}

printf("send successfully!\n");

  1. step 11:关闭连接同时退出进程

close(connfd);

exit(0);

  1. step 12:检查头文件和变量是否定义

客户端流程

  1. step 1:创建 socke() 套接字接口并判断

connfd = socket(AF_INET, SOCK_STREAM, 0);

if (connfd == -1)

{perror("socket failed");return -1;}

  1. step 2:设置服务器 IP 和 Port

memset (&seraddr, 0, sizeof(seraddr));

seraddr.sin_family = AF_INET;

seraddr.sin_port = htons(8888);

seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");

  1. step 3:发送连接请求并判断

ret = connect(connfd, (struct sockaddr *)&seraddr, sizeof(seraddr));

if (ret == -1)

{perror("connect faile");return -1;}

printf("connect sucessfully!\n");

  1. step 4:设置数据循环,并获取标准输入的数据

while (1)

{fgets(buf, sizeof(buf), stdin);

buf[strlen(buf)-1] = '\0';

...}

  1. step 5:发送数据并判断

ret = send(connfd, buf, sizeof(buf), 0);

if (ret == -1)

{perror("send faile");return -1;}

printf("send successfully!");

  1. step 6:设置退出条件

if (!strncmp("quit", buf, 4))

break;

  1. step 7:接收数据

ret = recv(connfd, buf, sizeof(buf), 0);

if (ret == -1)

{perror("recv faile");return -1;}

printf("%s\n", buf);

  1. step 8:关闭连接

close(connfd);

  1. step 9:检查头文件和变量是否定义

这篇关于网络通信1—TCP程序编写步骤(参照 Ubuntu 16.04 版本)(转载)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/506915

相关文章

将Java程序打包成EXE文件的实现方式

《将Java程序打包成EXE文件的实现方式》:本文主要介绍将Java程序打包成EXE文件的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录如何将Java程序编程打包成EXE文件1.准备Java程序2.生成JAR包3.选择并安装打包工具4.配置Launch4

Java程序进程起来了但是不打印日志的原因分析

《Java程序进程起来了但是不打印日志的原因分析》:本文主要介绍Java程序进程起来了但是不打印日志的原因分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java程序进程起来了但是不打印日志的原因1、日志配置问题2、日志文件权限问题3、日志文件路径问题4、程序

将Java项目提交到云服务器的流程步骤

《将Java项目提交到云服务器的流程步骤》所谓将项目提交到云服务器即将你的项目打成一个jar包然后提交到云服务器即可,因此我们需要准备服务器环境为:Linux+JDK+MariDB(MySQL)+Gi... 目录1. 安装 jdk1.1 查看 jdk 版本1.2 下载 jdk2. 安装 mariadb(my

如何在Mac上安装并配置JDK环境变量详细步骤

《如何在Mac上安装并配置JDK环境变量详细步骤》:本文主要介绍如何在Mac上安装并配置JDK环境变量详细步骤,包括下载JDK、安装JDK、配置环境变量、验证JDK配置以及可选地设置PowerSh... 目录步骤 1:下载JDK步骤 2:安装JDK步骤 3:配置环境变量1. 编辑~/.zshrc(对于zsh

Android Studio 配置国内镜像源的实现步骤

《AndroidStudio配置国内镜像源的实现步骤》本文主要介绍了AndroidStudio配置国内镜像源的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、修改 hosts,解决 SDK 下载失败的问题二、修改 gradle 地址,解决 gradle

SpringBoot实现微信小程序支付功能

《SpringBoot实现微信小程序支付功能》小程序支付功能已成为众多应用的核心需求之一,本文主要介绍了SpringBoot实现微信小程序支付功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作... 目录一、引言二、准备工作(一)微信支付商户平台配置(二)Spring Boot项目搭建(三)配置文件

浅谈配置MMCV环境,解决报错,版本不匹配问题

《浅谈配置MMCV环境,解决报错,版本不匹配问题》:本文主要介绍浅谈配置MMCV环境,解决报错,版本不匹配问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录配置MMCV环境,解决报错,版本不匹配错误示例正确示例总结配置MMCV环境,解决报错,版本不匹配在col

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

Ubuntu中远程连接Mysql数据库的详细图文教程

《Ubuntu中远程连接Mysql数据库的详细图文教程》Ubuntu是一个以桌面应用为主的Linux发行版操作系统,这篇文章主要为大家详细介绍了Ubuntu中远程连接Mysql数据库的详细图文教程,有... 目录1、版本2、检查有没有mysql2.1 查询是否安装了Mysql包2.2 查看Mysql版本2.

Win11安装PostgreSQL数据库的两种方式详细步骤

《Win11安装PostgreSQL数据库的两种方式详细步骤》PostgreSQL是备受业界青睐的关系型数据库,尤其是在地理空间和移动领域,:本文主要介绍Win11安装PostgreSQL数据库的... 目录一、exe文件安装 (推荐)下载安装包1. 选择操作系统2. 跳转到EDB(PostgreSQL 的