win32 tcp文件传输并发服务器

简介: #include#include #include #include #pragma comment(lib,"ws2_32.lib")#define PORT 9999#define IPADDR "127.
#include<stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <string.h>

#pragma comment(lib,"ws2_32.lib")

#define PORT 9999
#define IPADDR "127.0.0.1"
#define BACKLOG 20
#define FILENAME 200
#define LENGTH 200
#define BUFFERSIZE 1024

struct FILEHEAD //FILE-head  struct
{
	char filename[LENGTH];//file name
	unsigned int length;//the byte of the file

};

struct FILEDATA //FILE-data  struct
{
	char filename[LENGTH];//file name
	char package[BUFFERSIZE];//package data
	unsigned int length;//the byte of the file
	unsigned int index;//index of the package

};

struct sockaddr_in clientaddr;  //Definition of the external variable for thread function call

void getFileInformation(FILEHEAD file)
{
	printf( "file information :\n" );
	printf( "  Filename: %s\n", file.filename );
	//printf( "  Ext: %s\n", file.ext );
	printf( " the file length is: %ld btye\n", file.length );
}

void showClientinfo()
{
	//获取当前系统时间
	SYSTEMTIME st;
	GetLocalTime(&st);
	char SysDate[30];
	//将systime中的时间转变为字符串存入SysDate[30];
	sprintf(SysDate, "%4d-%2d-%2d %2d:%2d:%2d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
	//Server显示客户端信息
	printf("%s Recv from Client [%s:%d] : %s\n", SysDate, inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
	//服务器向客户端回显信息
}

DWORD WINAPI requestThread(LPVOID lparam)
{
	FILEHEAD filehead;
	FILEDATA filedata;
	SOCKET newsock=(SOCKET)(LPVOID)lparam;
	//char buf[BUFFERSIZE]={0};
	memset(&filehead,0,sizeof(filehead));
	memset(&filedata,0,sizeof(filedata));

	showClientinfo();

	//printf("等待文件头信息 ...\n");

	int length_file_info=recv(newsock,(char *)&filehead,sizeof(filehead),0);
	if (SOCKET_ERROR==length_file_info)
	{
		printf("receive failed!\n");
		closesocket(newsock);
		return -1;
		
	}
	if (length_file_info<=0)
	{
		exit(1);//异常退出
	}

	getFileInformation(filehead);//打印文件信息

	FILE *fp=NULL;
	fp=fopen(filehead.filename,"wb+");
	if (NULL==fp)
	{
		perror("fail to build the file!!!\n");
		exit(1);
	}
	
	//printf("要接收的文件名为:");
	//printf(filehead.filename);//打印文件名	
	//printf ("\n catch file now....\n");
	
	int recv_length=0;//接收到字节的长度
	
	//Sleep(100);
	
	printf("开始接收...\n");
	filedata.index=0;
	while (1)
	{
		recv_length=recv(newsock,(char *)&filedata,sizeof(filedata),0);
		if (recv_length == SOCKET_ERROR)
		{
			printf("recv failed !\n");
			closesocket(newsock);
			//WSACleanup();
			return -1;
		}
		
		fwrite(filedata.package,1,BUFFERSIZE,fp);
		if (0==recv_length)
		{
			break;
		}
		//printf("第%d块接收成功!\n",filedata.index);
	}
	printf("\n接收完成...\n\n");
	
	fflush(fp);
	fclose(fp);
	fp=NULL;
	
	return 0;
}

int main(int argc,char *argv[])
{
	//初始化winsock版本信息,加载动态链接库(dll)
	WSADATA wsData;
	if (WSAStartup(MAKEWORD(2,2),&wsData)!=0)
	{
		printf("WSAStartup failed !!!\n");
		return -1;
	}
	
	//创建套接字
	SOCKET socklisten;
	if((socklisten=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET)
	{
		printf("socket failed!!!\n");
		WSACleanup();
		return -1;
	}
	
	//设置服务器地址
	struct sockaddr_in servaddr;
	
	memset(&servaddr,0,sizeof(servaddr));
	servaddr.sin_family=AF_INET;
	servaddr.sin_port=htons(PORT);
	servaddr.sin_addr.S_un.S_addr=inet_addr(IPADDR);
	
	//绑定socket地址结构到监听套接字
	if (bind(socklisten,(sockaddr *)&servaddr,sizeof(servaddr))!=0)
	{
		printf("binding failed!!!\n");
		closesocket(socklisten);
		WSACleanup();
	}
	
	//在server上运行监听
	if (listen(socklisten,20)!=0)
	{
		printf("listen failed !!!\n");
		closesocket(socklisten);
		WSACleanup();
		return -1;
	}
	
	//接收客户端的连接请求
	printf("TCP server is start!!!\n");
	
	//clientaddrlength要有初值,
	int client_addr_length = sizeof(clientaddr);
	memset(&clientaddr,0,client_addr_length);
	SOCKET connect;
	
	//循环等待
	while (1)
	{
		if ((connect=accept(socklisten,(sockaddr *)&clientaddr,&client_addr_length))==INVALID_SOCKET)
		{
			printf("accept failed!!!\n");
			closesocket(connect);
			WSACleanup();
			return -1;
		}
		
		//创建新线程
		DWORD ThreadID;
		CreateThread(NULL,0,requestThread,(LPVOID)connect,0,&ThreadID);
	}
	
	

}


 

相关文章
|
3月前
|
网络协议
端口最多只有65535个,为什么服务器能承受百万并发
服务器通过四元组(源IP、源端口、目标IP、目标端口)识别不同TCP连接,每条连接对应独立socket。数据包携带四元组信息,服务端据此查找对应socket进行通信。只要四元组任一元素不同,即视为新连接,可创建独立socket。资源充足时,单进程可支持百万级并发连接,socket与端口非一一对应。
209 10
端口最多只有65535个,为什么服务器能承受百万并发
|
域名解析 网络协议 数据库
TCP/IP服务器
【10月更文挑战第20天】TCP/IP服务器
309 65
|
12月前
|
缓存 网络协议 Java
【JavaEE】——TCP回显服务器(万字长文超详细)
ServerSocket类,Socket类,PrintWriter缓冲区问题,Socket文件释放问题,多线程问题
|
网络协议 Java API
【网络】TCP回显服务器和客户端的构造,以及相关bug解决方法
【网络】TCP回显服务器和客户端的构造,以及相关bug解决方法
222 2
|
存储 网络协议 Java
【网络】UDP和TCP之间的差别和回显服务器
【网络】UDP和TCP之间的差别和回显服务器
182 1
|
网络协议 Python
Python创建一个TCP服务器
Python创建一个TCP服务器
149 0
|
网络协议 安全 Unix
6! 用Python脚本演示TCP 服务器与客户端通信过程!
6! 用Python脚本演示TCP 服务器与客户端通信过程!
361 1
|
网络协议 数据处理 C语言
利用C语言基于poll实现TCP回声服务器的多路复用模型
此代码仅为示例,展示了如何基于 `poll`实现多路复用的TCP回声服务器的基本框架。在实际应用中,你可能需要对其进行扩展或修改,以满足具体的需求。
277 0
|
机器学习/深度学习 人工智能 网络协议
TCP/IP五层(或四层)模型,IP和TCP到底在哪层?
TCP/IP五层(或四层)模型,IP和TCP到底在哪层?
382 4
|
域名解析 网络协议
IP协议, TCP协议 和DNS 服务分别是干什么的?
大家好,我是阿萨。昨天讲解了网络四层协议[TCP/IP协议族分为哪4层?]今天我们学习下IP 协议, TCP 协议和DNS 协议分别是干什么的。
484 0
IP协议, TCP协议 和DNS 服务分别是干什么的?

热门文章

最新文章