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

📄 server.cpp

📁 linux网络程序设计 几个小程序以及编译命令
💻 CPP
字号:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <setjmp.h>
#include <string.h>
#include <sys/time.h>

#define DEFAULT_PORT 7000
#define DEFAULT_BUFFER_SIZE 4096

//数据传送函数
void transData(int sClient);

//尝试新建文件函数,成功则返回true
int newFile(const char *fname,long flen);

main()
{
	printf("\nServer starting...\n");	

	
	int sListen,sClient;
	struct sockaddr_in local,client;
	
	//建立监听套接字
	sListen=socket(AF_INET,SOCK_STREAM,0);
	if(sListen==-1)
	{
		printf("socket() failed\n");
		return 1;
	}

	//绑定本地地址
	local.sin_addr.s_addr=htonl(INADDR_ANY);
	local.sin_family=AF_INET;
	local.sin_port=htons(DEFAULT_PORT);	
	if(bind(sListen,(struct sockaddr *)&local,
		sizeof(local))==-1)
	{
		printf("bind() failed\n");
		return 1;
	}
	printf("Server started.\n");
	
	//设定监听模式,限制同一时间仅允许1个连接(不一定有效)
	//即使多于1个连接,后来的连接必须等待欢迎信息
	//可确保只有1个连接能进行数据传送
	listen(sListen,0);	
	printf("Waiting for connection...\n");

	int iAddrSize;
	while(true)
	{
		//接收用户连接
		iAddrSize=sizeof(client);
		sClient=accept(sListen,(struct sockaddr *)&client,
						(socklen_t *)&iAddrSize);
		if(sClient==-1)
		{
			printf("accept() failed\n");
			break;
		}		
		printf("\nA connection has been established.\n");
		
		//进行数据传送
		transData(sClient);
	}
	close(sListen);
	return 0;
}

void transData(int sock)
{
	//发送欢迎信息
	write(sock,"hello",6);

	char *buff=new char[DEFAULT_BUFFER_SIZE];		
	
	char *szFileName=new char[100];
	long flen;
	FILE *fp=NULL;

	int ret;
	int index;
	
	//设置send/recv超时
	struct timeval timeout={2,0};
	int bread=setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,
		(char *)&timeout,sizeof(timeout));
	if(bread==-1)
	{
		printf("setsockopt(SO_RCVTIMEO) failed\n");
		return;
	}
	bread=setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,
		(char *)&timeout,sizeof(timeout));
	if(bread==-1)
	{
		printf("setsockopt(SO_SNDTIMEO) failed\n");
		return;
	}

	//以循环方式接收处理消息
	do
	{
		ret=read(sock,buff,DEFAULT_BUFFER_SIZE);
				
		if((!strcmp(buff,"bye"))||ret<=0)
		{
			//传送结束
			if(fp!=NULL)
			{fclose(fp);}

			break;
		}
		else if(!strcmp(buff,"info"))
		{
			//接收文件信息
			strcpy(szFileName,buff+5);
			printf("File name: %s\n",szFileName);
			flen=*( (int *) (buff+5+strlen(szFileName)+1) );
			printf("File size: %d\n",flen);
			
			//尝试新建文件
			if(!newFile(szFileName,flen))
			{
				write(sock,"exist",6);
				break;
			}
			//打开文件
			if((fp=fopen(szFileName,"ab"))==NULL)
			{
				write(sock,"openerr",8);
				break;
			}

			//准备就绪,提示客户端
			write(sock,"ready",6);
		}
		else if(!strcmp(buff,"data"))
		{
			//接收数据
			if(fp==NULL)
			{
				printf("File isnot opened.\n");
				break;
			}

			index=*((int *)(buff+5));
			fseek(fp,index,SEEK_SET);
			printf("recv --- %d: %dbytes\n",index,ret-9);
			fwrite(buff+9,sizeof(char),ret-9,fp);
		}
		else
		{
			break;
		}
	}
	while(true);
	
	close(sock);
	printf("Connection terminated.\n");
}


int newFile(const char *fname,long flen)
{
	FILE *fp;
	if((fp=fopen(fname,"r"))!=NULL)
	{
		printf("File exists already.\n");//文件已存在
		fclose(fp);
		return false;
	}

	return true;
}

⌨️ 快捷键说明

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