TCP回射服务器

2024-04-21 17:08
文章标签 服务器 tcp 回射

本文主要是介绍TCP回射服务器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

TCP回射服务器

所谓的回射服务器就是说从客户端输入,经过服务器,然后在客户端输出,用一张图来表示最合理。

081520265032957这里写图片描述

这就是所谓的回射服务器,我们可以去看看《unix网络编程卷一》。

它的一个大概思路就是:

服务器是一个并发服务器,所以当连接到来时,会fork一个子进程来对客户请求进行处理。其他部分就按简单的客户-服务器通信的步骤来写就行,客户端:socket()—>connect()—>处理函数;服务器:socket()—>bind()—>listen()—>accept()—>处理函数

程序代码:

utili.h

#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<string.h>
#include<netinet/in.h>
#include<signal.h>
#define LISTENQ 1024
#define SERV_PORT 9857#define BUFSIZE 4096

ser.c

#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<string.h>
#include<netinet/in.h>
#include<signal.h>
#define LISTENQ 1024
#define SERV_PORT 9857#define BUFSIZE 4096
wz@wz-machine:~/linux/socket/2$ cat ser.c 
#include"utili.h"void str_echo(int sockfd)
{ssize_t n;char buf[BUFSIZE];while((n=read(sockfd,buf,BUFSIZE)) > 0)write(sockfd,buf,n);
}
void sig_chld(int signo)
{pid_t pid;int stat;while((pid = waitpid(-1,&stat,WNOHANG))>0)printf("child %d terminated\n",pid);return ;
}
int main()
{int confd,listenfd;struct sockaddr_in cliaddr,servaddr;pid_t childpid;socklen_t clien;int status;char buf[BUFSIZE];bzero(&servaddr,sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(SERV_PORT);listenfd = socket(AF_INET,SOCK_STREAM,0);if(listenfd == -1)printf("socket error\n");status = bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr));if(status == -1)printf("bind error\n");status = listen(listenfd,LISTENQ);signal(SIGCHLD,sig_chld);while(1){clien = sizeof(cliaddr);confd = accept(listenfd,(struct sockaddr*)&cliaddr,&clien);if(confd == -1)printf("accept error\n");if((childpid = fork())==0){printf("connet from %s,port %d\n",inet_ntop(AF_INET,&cliaddr.sin_addr,buf,sizeof(buf)),ntohs(cliaddr.sin_port));close(listenfd);str_echo(confd);close(confd);exit(0);}close(confd);}
//  return 0;
}

cli.c

#include"utili.h"void str_cli(FILE* fp,int sockfd)
{printf("connect success\n");char send[BUFSIZE],recv[BUFSIZE];while(fgets(send,BUFSIZE,fp)!=NULL){write(sockfd,send,strlen(send));read(sockfd,recv,BUFSIZE);fputs(recv,stdout);bzero(recv,BUFSIZE);}
}int main(int argc,char **argv)
{int sockfd;struct sockaddr_in servaddr;socklen_t clien;int status;char buf[BUFSIZE];bzero(&servaddr,sizeof(servaddr));servaddr.sin_family = AF_INET;
//  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(SERV_PORT);inet_pton(AF_INET,argv[1],&servaddr.sin_addr);sockfd = socket(AF_INET,SOCK_STREAM,0);if(sockfd == -1)printf("socket error\n");status = connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr));if(status == -1)printf("connecd error\n");str_cli(stdin,sockfd);return 0;
//  exit(0);
}

这里面用到了signal函数,捕获SIGCHLD ,用来处理僵尸进程,在函数中调用了waitpid来处理子进程。其中waitpid中值-1表示等待第一个终止的子进程 ,最常用的选项是WNOHANG,它告知内核在没有已终止子进程时不要阻塞。

在网络编程时可能会遇到的三种情况:

(1)当fork子进程时,必须捕获SIGCHLD信号。

(2)当捕获信号时,必须处理被中断的系统调用。

(3)SIGCHLD的信号处理函数必须正确编写,应使用waitpid函数以免留下僵死进程。

在客户端和服务器中传输注意事项

(1)不同的实现以不同的格式存储二进制数。(大端和小端)

(2)不同的实现在存储相同的C数据类型上可能存在差异。(32位系统和64位系统)

(3)不同的实现给结构打包的方式存在差异,这取决于各种数据类型所用的位数以及机器的对齐限制。

因此,穿越套接口传送二进制结构绝不是明智的选择。

解决这种数据格式问题有两个常用的方法:

(1)把所有的数值数据作为文本串来传递。当然这里假设客户和服务器主机具有相同的字符集。

(2)显示定义所支持数据类型的二进制格式(位数、大端或小端),并以这样的格式在客户和服务器之间传递所有数据。

参考:《unix网络编程卷1》

这篇关于TCP回射服务器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Nginx服务器部署详细代码实例

《Nginx服务器部署详细代码实例》Nginx是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务,:本文主要介绍Nginx服务器部署的相关资料,文中通过代码... 目录Nginx 服务器SSL/TLS 配置动态脚本反向代理总结Nginx 服务器Nginx是一个‌高性

Prometheus+cpolar如何在手机上也能监控服务器状态?

《Prometheus+cpolar如何在手机上也能监控服务器状态?》本文强调了通过Cpolar这一内网穿透工具,轻松突破Prometheus仅限于局域网访问的限制,实现外网随时随地访问监控数据,教你... 目录前言1.安装prometheus2.安装cpolar实现随时随地开发3.配置公网地址4.保留固定

Linux服务器数据盘移除并重新挂载的全过程

《Linux服务器数据盘移除并重新挂载的全过程》:本文主要介绍在Linux服务器上移除并重新挂载数据盘的整个过程,分为三大步:卸载文件系统、分离磁盘和重新挂载,每一步都有详细的步骤和注意事项,确保... 目录引言第一步:卸载文件系统第二步:分离磁盘第三步:重新挂载引言在 linux 服务器上移除并重新挂p

Apache服务器IP自动跳转域名的问题及解决方案

《Apache服务器IP自动跳转域名的问题及解决方案》本教程将详细介绍如何通过Apache虚拟主机配置实现这一功能,并解决常见问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,... 目录​​问题背景​​解决方案​​方法 1:修改 httpd-vhosts.conf(推荐)​​步骤

Linux云服务器手动配置DNS的方法步骤

《Linux云服务器手动配置DNS的方法步骤》在Linux云服务器上手动配置DNS(域名系统)是确保服务器能够正常解析域名的重要步骤,以下是详细的配置方法,包括系统文件的修改和常见问题的解决方案,需要... 目录1. 为什么需要手动配置 DNS?2. 手动配置 DNS 的方法方法 1:修改 /etc/res

Nginx屏蔽服务器名称与版本信息方式(源码级修改)

《Nginx屏蔽服务器名称与版本信息方式(源码级修改)》本文详解如何通过源码修改Nginx1.25.4,移除Server响应头中的服务类型和版本信息,以增强安全性,需重新配置、编译、安装,升级时需重复... 目录一、背景与目的二、适用版本三、操作步骤修改源码文件四、后续操作提示五、注意事项六、总结一、背景与

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2

Linux搭建ftp服务器的步骤

《Linux搭建ftp服务器的步骤》本文给大家分享Linux搭建ftp服务器的步骤,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录ftp搭建1:下载vsftpd工具2:下载客户端工具3:进入配置文件目录vsftpd.conf配置文件4:

Linux查询服务器 IP 地址的命令详解

《Linux查询服务器IP地址的命令详解》在服务器管理和网络运维中,快速准确地获取服务器的IP地址是一项基本但至关重要的技能,下面我们来看看Linux中查询服务器IP的相关命令使用吧... 目录一、hostname 命令:简单高效的 IP 查询工具命令详解实际应用技巧注意事项二、ip 命令:新一代网络配置全

Python开发简易网络服务器的示例详解(新手入门)

《Python开发简易网络服务器的示例详解(新手入门)》网络服务器是互联网基础设施的核心组件,它本质上是一个持续运行的程序,负责监听特定端口,本文将使用Python开发一个简单的网络服务器,感兴趣的小... 目录网络服务器基础概念python内置服务器模块1. HTTP服务器模块2. Socket服务器模块