Linux实验八:流式套接字编程

目录

    • 一、实验目的
    • 二、实验内容
    • 三、实验环境
    • 四、参考代码
    • 五、实验步骤
      • 步骤1. 编辑源代码blockserver.c和blockclient.c
      • 步骤2. 编译源代码blockserver.c和blockclient.c
      • 步骤3. 运行可执行程序blockserver和blockclient
    • 六、实验结果
    • 七、实验总结


一、实验目的

1、深入理解 TCP/IP 模型相关概念;
2、掌握流式套接字 socket 相关的数据结构,如 sokkaddr,sockaddr_in 等;
3、掌握流式套接字通讯时常用的函数,如 socket,connect,listen,accept 等。

二、实验内容

在网络环境中使用流式套接字完成以下内容:客户端进程 A 向服务器进程 B 发送一个字符,B进程将接收到 A 进程的字符,反之亦然。

实验的主要内容是编写一个TCP客户端程序,该程序能够连接到指定的服务器地址和端口,发送用户输入的消息,并接收服务器的回复。在这个过程中,我们需要完成以下关键步骤:

  1. 创建套接字:利用socket()函数创建一个TCP套接字。
  2. 设置服务器地址:配置服务器的IP地址和端口号。
  3. 连接服务器:使用connect()函数连接到服务器。
  4. 数据交互:通过write()和read()函数实现与服务器的数据交换。
  5. 关闭套接字:在通信结束后,关闭套接字释放资源。

三、实验环境

虚拟机软件:VMware 16 Pro
Linux操作系统版本:CentOS-7-64位

四、参考代码

blockserver.c

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>#define BUFSIZE 1024
#define PORT 5058int main(int argc, char *argv[]){int listen_fd, client_fd;struct sockaddr_in server_addr,client_addr;ssize_t server_len, client_len ;char buffer[BUFSIZE];int real_read = -1;memset(buffer, BUFSIZE, 0);// create socket, socket just like file descriptorlisten_fd = socket(PF_INET, SOCK_STREAM, 0); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(PORT);server_addr.sin_addr.s_addr = INADDR_ANY;server_len = sizeof(struct sockaddr_in);// bind listen_fd and server socket addressbind(listen_fd, (struct sockaddr *) &server_addr, server_len);// set listen queuelisten(listen_fd, 5);// wait for client to connect// note: accept's third argment is client socket address's pointerclient_len = sizeof(struct sockaddr_in);client_fd = accept(listen_fd, (struct sockaddr *) &client_addr, &client_len);while(1){real_read = read(client_fd, buffer, BUFSIZE);printf("FROM CLIENT: %s", buffer);if( strncmp(buffer,"END",3) == 0) break;fgets(buffer, BUFSIZE,stdin);write(client_fd, buffer,real_read);  // echomemset(buffer,BUFSIZE, 0);}close(client_fd);close(listen_fd);return 0; 
}

blockclient.c

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>#define BUFSIZE 1024
#define PORT 5058int main(int argc, char* argv[]){int server_fd;struct sockaddr_in server_addr;char buffer[BUFSIZE];    memset(buffer, BUFSIZE, 0);server_addr.sin_family = AF_INET;// string -> struct in_addrserver_addr.sin_addr.s_addr = inet_addr("127.0.0.1");server_addr.sin_port = htons(PORT);// create client socketserver_fd = socket(PF_INET, SOCK_STREAM, 0);// connect server connect(server_fd,(struct sockaddr *)  &server_addr, sizeof(server_addr));while(1){fgets(buffer, BUFSIZE,stdin);write(server_fd, buffer, BUFSIZE);if(strncmp(buffer,"END",3)==0)break;memset(buffer, BUFSIZE, 0);read(server_fd,buffer,BUFSIZE);printf("From Server: %s",buffer);}close(server_fd);return 0;
}

五、实验步骤

步骤1. 编辑源代码blockserver.c和blockclient.c

源代码blockserver.c和blockclient.c内容见上述参考代码。

mkdir test8
cd test8
vim blockserver.c
vim blockclient.c

源代码blockserver.c

在这里插入图片描述

  首先,定义了缓冲区大小BUFSIZE和服务器监听的端口号PORT。定义了监听套接字listen_fd和客户端套接字client_fd,以及服务器地址server_addr和客户端地址client_addr结构体。buffer数组用于存储接收和发送的数据,real_read用于记录实际读取的字节数。
  接着,使用memset函数将buffer数组的所有元素初始化为0。创建一个 TCP 套接字,并将其文件描述符存储在listen_fd中。设置服务器地址结构体server_addr的成员,包括地址族为 IPv4 (AF_INET),端口号为PORT,IP 地址为任意可用地址 (INADDR_ANY)。将listen_fd套接字与指定的server_addr绑定,使服务器能够接收客户端连接请求。
  然后,开始监听传入的连接请求,允许最多5个等待连接的队列。接受客户端的连接请求,并创建一个新的套接字client_fd用于与客户端通信。此函数会阻塞程序直到有客户端连接进来。处理通信,在一个无限循环中,服务器从client_fd套接字读取数据到buffer中。如果接收到的数据是 “END”,则退出循环。然后从标准输入 (stdin) 获取数据并将其写回client_fd套接字,实现了简单的回显功能。
  最后,在程序结束时关闭client_fdlisten_fd套接字,释放资源。

源代码blockclient.c

在这里插入图片描述

  首先,定义了缓冲区大小BUFSIZE和服务器监听的端口号PORT。声明了服务器套接字server_fd、服务器地址结构体server_addr和用于存储消息的缓冲区buffer。使用memsetbuffer初始化为0。
  接着设置了服务器地址结构体server_addr的成员:地址族为 IPv4 (AF_INET),服务器 IP 地址为本地回环地址127.0.0.1,端口为PORT。创建了 TCP 套接字server_fd,并使用connect函数连接到指定的服务器地址和端口。
  然后,在一个无限循环中,程序通过fgets获取用户输入的消息存入buffer,然后使用write函数将消息发送给服务器。如果用户输入了 “END”,则退出循环。接着使用read函数读取服务器的响应,将响应打印到控制台。
  最后,在程序结束时关闭客户端套接字server_fd,释放资源。

步骤2. 编译源代码blockserver.c和blockclient.c

gcc blockserver.c -o blockserver -g
gcc blockclient.c -o blockclient -g

在这里插入图片描述

步骤3. 运行可执行程序blockserver和blockclient

在第一个终端中,运行blockserver可执行文件。

./blockserver

在第二个终端中,运行blockclient可执行文件。

./blockclient

接下来,分别在服务端和客户端中输入一些字符串,都能互相接收到信息。

在这里插入图片描述

六、实验结果

运行结果如下:

在这里插入图片描述

七、实验总结

  在本次实验中,我们深入学习了如何在Linux环境下使用流式套接字(TCP套接字)来进行客户端-服务器通信。通过编写一个简单的TCP客户端程序,我们不仅掌握了基础的网络编程知识,还体验了实际动手编程的乐趣和挑战。
  在实验过程中,我首先熟悉了流式套接字的基本概念和相关系统调用。通过查阅资料和阅读代码示例,我逐步理解了每个函数的作用及其参数的含义。例如,socket()函数用于创建套接字,connect()函数用于建立连接,write()和read()函数分别用于发送和接收数据。
  在编写客户端程序时,遇到的第一个挑战是如何正确设置服务器地址结构体sockaddr_in。通过仔细阅读文档并结合代码示例,我了解到需要设置地址族为AF_INET,IP地址可以使用inet_addr()函数转换,端口号则通过htons()函数转换为网络字节序。
  另一个挑战是处理与服务器的通信。在实现循环发送和接收消息时,我学会了使用fgets()来获取用户输入,并通过strncmp()函数判断是否输入了“END”从而决定是否退出循环。同时,通过反复测试和调试,确保程序能够正确地发送和接收数据,并处理可能的错误情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/27490.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式操作系统_3.操作系统内核架构

内核是操作系统的核心部分&#xff0c;它管理着系统的各种资源。内核可以看成连接应用程序和硬件的一座桥梁&#xff0c;是直接运行在硬件上的最基础的软件实体。目前从内核架构来划分&#xff0c;可分为宏内核&#xff08;Monolithic Kernel&#xff09;和微内核&#xff08;M…

网络编程(一)基本概念、TCP协议

文章目录 一、概念&#xff08;一&#xff09;网络发展阶段1. ARPAnet阶段2. TCP/IP两个协议阶段3. 网络体系结构和OSI开放系统互联模型4. TCP/IP协议簇体系结构&#xff08;1&#xff09; 应用层&#xff1a;&#xff08;2&#xff09;传输层&#xff1a;&#xff08;3&#x…

【STM32】GPIO输出(江科大)

一、GPIO简介 1.GPIO&#xff1a;通用输入输出口 2.可配置为8种输入输出模式 3.引脚电平&#xff1a;0-3.3V&#xff08;输出最大3.3V&#xff09;&#xff0c;部分引脚可容忍5V&#xff08;输入&#xff0c;有FT&#xff09; 4.输出模式下&#xff0c;可控制端口输出高低电平…

网络学习(14)|RESTful API设计:构建优雅的Web服务

文章目录 设计原则最佳实践命名与URI设计状态码与响应格式HTTP状态码详解响应格式选择 在当今的互联网世界中&#xff0c;RESTful API已成为构建可扩展、可维护和高性能Web服务的标准。本文将深入探讨RESTful API的设计原则、资源命名与URI设计的最佳实践&#xff0c;以及请求与…

linux系统宝塔服务器temp文件夹里总是被上传病毒php脚本

目录 简介 上传过程 修复上传漏洞 tmp文件夹总是被上传病毒文件如下图: 简介 服务器时不时的会发送短信说你服务器有病毒, 找到了这个tmp文件, 删除了之后又有了。 确实是有很多人就这么无聊, 每天都攻击你的服务器。 找了很久的原因, 网上也提供了一大堆方法,…

通过语言大模型类学习python,卡哪问哪(一)

代码语法学习&#xff0c;代码解析 import matplotlib.pyplot as plt import numpy as np import PIL import tensorflow as tffrom tensorflow import keras from tensorflow.keras import layers from tensorflow.keras.models import Sequential 一、语法解析 &#xff08;…

themleaf 页面弹层取值

themleaf 页面弹层取值 创作背景themleaf页面事件onbluronclick 页面参数提交 创作背景 个人在日常开发中&#xff0c;遇到了一个需求页面&#xff0c;页面交互较多&#xff0c;用到的事件也很丰富&#xff0c;特此记录&#xff0c;方便后续查找也方便有需要的开发者采用&…

10 SpringBoot 静态资源访问

我们在开发Web项目的时候&#xff0c;往往会有很多静态资源&#xff0c;如html、图片、css等。那如何向前端返回静态资源呢&#xff1f; 以前做过web开发的同学应该知道&#xff0c;我们以前创建的web工程下面会有一个webapp的目录&#xff0c;我们只要把静态资源放在该目录下…

从零手写实现 nginx-23-nginx 对于 cookie 的操作

前言 大家好&#xff0c;我是老马。很高兴遇到你。 我们为 java 开发者实现了 java 版本的 nginx https://github.com/houbb/nginx4j 如果你想知道 servlet 如何处理的&#xff0c;可以参考我的另一个项目&#xff1a; 手写从零实现简易版 tomcat minicat 手写 nginx 系列 …

信号与系统实验MATLAB-实验2-连续时间系统的时域分析

实验二 连续时间系统的时域分析 一、实验目的 1、掌握连续时间信号卷积及其MATLAB实现方法&#xff1b; 2、掌握连续系统的冲激响应、阶跃响应及其MATLAB实现方法&#xff1b; 3、掌握利用MATLAB求LTI系统响应的方法&#xff1b; 4、掌握利用MATLAB求函数卷积和解微分方程…

网络IO模型:BIO NIO AIO 的区别!!!

BIO是同步阻塞I/O模型&#xff0c;它使用一个线程来处理一个请求&#xff0c;如果这个请求没有被处理完&#xff0c;这个线程就会一直等待&#xff0c;直到请求处理完成。这种模型适用于连接数较小的情况。 NIO是同步非阻塞I/O模型&#xff0c;它使用单个线程来处理多个请求&a…

APM之:卡顿监控

方案一&#xff1a;参考了ANR-WatchDog机制 ANR-WatchDog机制原理不复杂&#xff0c;它内部启动了一个子线程&#xff0c;定时通过主线程Handler发送Message&#xff0c;然后定时去检查Message的处理结果。 通俗来说就是利用了Android系统MessageQueue队列的排队处理特性。 …

学习grdecl文件格式之后的事情

学习了grdecl文件格式&#xff0c;搞地质的专业人士都知道&#xff0c;这是专门用在地质上的油藏软件&#xff08;个人感觉就是斯伦贝谢的Petrel的&#xff09;的一种文件格式&#xff0c;正好自己也在学习三维的开发&#xff0c;顺手写了一个简单的读取grdecl算法&#xff0c;…

Vue3【十九】自定义Hooks钩子 将数据和方法分组

Vue3【十九】自定义Hooks钩子 将数据和方法分组 Vue3【十九】自定义Hooks钩子 将数据和方法分组 每个分组都可以放置 各种生命周期钩子 分组和可以使用计算属性等 案例截图 目录结构 代码 person.vue <template><div class"person"><h2>Vue3自定…

Linux指令学习(4)

目录 0.普通用户和root用户之间的切换 1.head/tail指令 2.管道 3.date命令 4.三个查找相关的指令 5.文件过滤grep 6.打包和压缩 5.zip/unzip指令 0.普通用户和root用户之间的切换 &#xff08;1&#xff09;这个我们之前不是经常使用这个root用户吗&#xff0c;现在随着…

NLP--逻辑回归

1.定义 如何解决二元分类问题&#xff0c;除了上节我们谈到的贝叶斯分类器&#xff0c;我们可以通过计算数据属于不同类别的概率进行分类的逻辑回归。虽然有回归二字&#xff0c;但逻辑回归解决的是分类问题&#xff0c;也可以用于两类以上的多分类问题。 2.方法 概率是介于0到…

python操作jenkins

参考链接&#xff1a; python操作jenkins

数据结构笔记39-48

碎碎念&#xff1a;想了很久&#xff0c;不知道数据结构这个科目最终该以什么笔记方式呈现出来&#xff0c;是纸质版还是电子版&#xff1f;后来想了又想&#xff0c;还是电子版吧&#xff1f;毕竟和计算机有关~&#xff08;啊哈哈哈哈哈哈哈&#xff09; 概率论已经更新完了&…

代码随想录训练营第八天 151反转字符串中的单词 右旋字符串

第一题&#xff1a; 原题链接&#xff1a;151. 反转字符串中的单词 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 先把首尾的空格去掉&#xff1a;找到第一个不是空格的字符&#xff0c;找到最后一个不是空格的字符。substr字符串为新的字符串t。 使用双指针&…