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

相关文章

Windows Server 2025 搭建NPS-Radius服务器的步骤

《WindowsServer2025搭建NPS-Radius服务器的步骤》本文主要介绍了通过微软的NPS角色实现一个Radius服务器,身份验证和证书使用微软ADCS、ADDS,具有一定的参考价... 目录简介示意图什么是 802.1X?核心作用802.1X的组成角色工作流程简述802.1X常见应用802.

使用Nginx配置文件服务器方式

《使用Nginx配置文件服务器方式》:本文主要介绍使用Nginx配置文件服务器方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 为什么选择 Nginx 作为文件服务器?2. 环境准备3. 配置 Nginx 文件服务器4. 将文件放入服务器目录5. 启动 N

SpringBoot快速搭建TCP服务端和客户端全过程

《SpringBoot快速搭建TCP服务端和客户端全过程》:本文主要介绍SpringBoot快速搭建TCP服务端和客户端全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录TCPServerTCPClient总结由于工作需要,研究了SpringBoot搭建TCP通信的过程

Go语言开发实现查询IP信息的MCP服务器

《Go语言开发实现查询IP信息的MCP服务器》随着MCP的快速普及和广泛应用,MCP服务器也层出不穷,本文将详细介绍如何在Go语言中使用go-mcp库来开发一个查询IP信息的MCP... 目录前言mcp-ip-geo 服务器目录结构说明查询 IP 信息功能实现工具实现工具管理查询单个 IP 信息工具的实现服

springboot上传zip包并解压至服务器nginx目录方式

《springboot上传zip包并解压至服务器nginx目录方式》:本文主要介绍springboot上传zip包并解压至服务器nginx目录方式,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录springboot上传zip包并解压至服务器nginx目录1.首先需要引入zip相关jar包2.然

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

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

基于Python打造一个可视化FTP服务器

《基于Python打造一个可视化FTP服务器》在日常办公和团队协作中,文件共享是一个不可或缺的需求,所以本文将使用Python+Tkinter+pyftpdlib开发一款可视化FTP服务器,有需要的小... 目录1. 概述2. 功能介绍3. 如何使用4. 代码解析5. 运行效果6.相关源码7. 总结与展望1

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

CentOS 7部署主域名服务器 DNS的方法

《CentOS7部署主域名服务器DNS的方法》文章详细介绍了在CentOS7上部署主域名服务器DNS的步骤,包括安装BIND服务、配置DNS服务、添加域名区域、创建区域文件、配置反向解析、检查配置... 目录1. 安装 BIND 服务和工具2.  配置 BIND 服务3 . 添加你的域名区域配置4.创建区域