⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 server.c

📁 老师编写的客户端服务器文件传送程序,在vmware redhat linux下测试能正常使用,相当经典
💻 C
字号:
#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include<netdb.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include <sys/signal.h> 
#include <sys/wait.h>   


#define SERVER_PORT 6667
#define LENGTH_OF_LISTEN_QUEUE 20
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512

void reaper(int sig)
{
    int status;
    //调用wait3读取子进程的返回值,使zombie状态的子进程彻底释放
    while(wait3(&status,WNOHANG,(struct rusage*)0) >=0)
        ;
}

int main(int argc,char**argv)
{
	//设置一个socket地址结构server_addr,代表服务器internet地址, 端口
	struct sockaddr_in server_addr;
	//把一段内存区的内容全部设置为0
	bzero(&server_addr,sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = htons(INADDR_ANY);
	server_addr.sin_port = htons(SERVER_PORT);
	
	//创建用于internet的流协议(TCP)socket,用server_socket代表服务器socket
	int server_socket = socket(AF_INET,SOCK_STREAM,0);
	if(server_socket<0)
	{
		printf("Create socket failed!\n");
		exit(1);
	}
	
	//把socket和socket地址结构联系起来
	if(bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr)))
	{
		printf("Server bind port: %d failed!\n",SERVER_PORT);
		exit(1);
	}
	
	//server_socket用于监听
	if(listen(server_socket,LENGTH_OF_LISTEN_QUEUE))
	{
		printf("Server listen failed!\n");
		exit(1);
	}
	
	//服务器端要一直运行
	while(1)
	{
		//定义客户端的socket地址结构client_addr
		struct sockaddr_in client_addr;
		socklen_t length = sizeof(client_addr);
		
		//接受一个到server_socket代表的socket的一个连接
		int new_server_socket = accept (server_socket,(struct sockaddr*)&client_addr,&length);
		if(new_server_socket<0)
		{
			printf("Server accept failed!\n");
			break;
		}
		int child_process_pid = fork(); //fork()后,子进程是主进程的拷贝
		if(child_process_pid == 0 )//如果当前进程是子进程,就执行与客户端的交互
        	{
			close(server_socket); //子进程中不需要被复制过来的server_socket
			char buffer[BUFFER_SIZE];
			bzero(buffer,BUFFER_SIZE);
			length = recv(new_server_socket,buffer,BUFFER_SIZE,0);
			if(length<0)
			{
				printf("Server receive data failed!\n");
				break;
			}
			char file_name[FILE_NAME_MAX_SIZE+1];
			bzero(file_name,FILE_NAME_MAX_SIZE+1);
			strncpy(file_name,buffer,strlen(buffer)>FILE_NAME_MAX_SIZE?FILE_NAME_MAX_SIZE:strlen(buffer));
			FILE * fp = fopen(file_name,"r");
			if(fp==NULL)
			{
				printf("File:\t%s not found\n",file_name);
			}
			else
			{
				bzero(buffer,BUFFER_SIZE);
				int file_block_length = 0;
				//发送buffer中的字符串到new_server_socket,实际是给客户端
				while((file_block_length =fread(buffer,sizeof(char),BUFFER_SIZE,fp))>0)
				{
					printf("file_block_length = %d\n",file_block_length);
					if(send(new_server_socket,buffer,file_block_length,0)<0)
					{
						printf("Send file:\t%s failed!",file_name);
						break;
					}
					bzero(buffer,BUFFER_SIZE);
				}
				fclose(fp);
				printf("File:\t%s transfer finished\n",file_name);
			}
			close(new_server_socket); 
            		exit(0);         
		}
		else if(child_process_pid > 0)     //如果当前进程是主进程 
            		close(new_server_socket);    //主进程中不需要用于同客户端交互的new_server_socket
	}
	
	//关闭监听用的socket
	close(server_socket);
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -