实验目的
实验目的:熟悉网络程序接口,了解TCP连接,掌握客户端软件设计的基本算法。
实验内容:写一个简单的网络文件服务器,该服务器能够为多个客户并发提供服务。服务器从客户端接收文件名,并用请求的文件内容应答客户端。
要求:
用多进程来实现并发;
为每个用户产生一个服务器进程;
要求用信号处理僵尸子进程;
与实验三编写客户端程序通信。客户端从终端输入名字,并显示回来的结果。
提示:服务器和客户端运行时用命令 “pstree” 来看创建的进程数是否正确。
实验截图
服务器端接收客户端传来的信息:
客户端接收服务器发送来的信息:
通过进程管理获取客户端与服务器的进程号:
通过ps au查看有无僵尸进程::
打印进程树:
实验步骤
服务器搭建步骤:
(1)在主函数之中建立参数传接端口
(2)定义TCP所需的网络参数,例如IP地址与端口号,配置sockaddr_in结构体。建立socket连接,建立char类型的缓冲区,定义至多传输4096字节的数据
(3)配置socket,bind,listen,启动accept使得服务器被动开启
(4)配置SIGCHLD至信号中,使得父进程能够主动清理僵尸子进程,根据用户连接使用fork创建子进程执行与客户端的通信。
(5)通过recv函数从TCP另一端接受数据,清空缓冲区,得到目标数据
(6)根据获得目标数据查找相对应文件,写入文件流中,输出文件内容后将内容发送给客户端
(7)关闭文件流与通信流,主进程退出
客户端搭建步骤:
(1)在主函数之中建立参数传接端口
(2)定义TCP所需的网络参数,例如IP地址与端口号,配置sockaddr_in结构体。建立socket连接,建立char类型的缓冲区,定义至多传输4096字节的数据
(3)填写服务器地址信息,定义传输格式,发起对服务器的连接,进行三次握手
(4)使用格式转化获得参数的长度,将参数发送到服务器端
(5)通过recv函数从TCP服务器端接受数据,清空缓冲区,得到目标数据
(6)从缓冲区中读取服务器传来的数据,显示在屏幕上
(6)关闭通信流,客户端退出,服务器阻塞
源码
服务器端代码
#include <sys/types.h>
#include <sys/fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <fstream>
#include <sstream>
#include <streambuf>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <sys/wait.h>
#define BUF_SIZE 4096 //限制最大发送4096个字节
using namespace std;
void waitchild(int sig) {
int status;
wait(&status);
}
int main(int argc, char *argv[])
{
int sock_fd, conn_fd,sendbytes;
struct sockaddr_in server_addr;
char buff[BUF_SIZE];//指定缓冲区长度
int ret;
int port_number = 12345;
int i;
pid_t pid;
signal(SIGCHLD, waitchild)