socket网络通信,传输文件,cc++

socket网络通信,传输文件,cc++,第1张

        当我们在实现网络通信时,避免不了发送文件,在这里给出基于tcp协议的文件传输,使用C语言编写,当然此程序亦可以传输字符串,详情请看我的上一篇博客http://t.csdn.cn/o0Qlv,以下先给出发送文件需要用到的函数,再对socket套接字进行初始化,最后给出main函数。

一,文件传输函数         1.接收文件
bool readFile(const char* fileName)
{
	FILE* read = fopen(fileName, "rb");//文件名,二进制打开
	if (!read)
	{
		perror("file open failed:\n");
		return false;
	}

	//获取文件大小
	fseek(read, 0, SEEK_END);//将文件位置指针移动到最后
	g_fileSzie=ftell(read);//
	fseek(read, 0, SEEK_SET);//移动到开头
	printf("filesize :%d\n",g_fileSzie);

	//分配内存
	g_fileBuf = calloc(g_fileSzie, sizeof(char));//申请内存,初始化为0
	if (!g_fileBuf)
	{
		return false;		
	}
	//读入内存
	fread(g_fileBuf, sizeof(char), g_fileSzie,read);

	fclose(read);
	return true;
}
        2.保存文件
bool saveFile(const char* fileName)
{

	FILE* write = fopen(fileName, "wb");//文件名
	if (!write)
	{
		perror("file open failed:\n");
		return false;
	}

	//读入内存
	fwrite(g_fileBuf, sizeof(char), g_fileSzie,write);
	fclose(write);
	return true;
}
        3.发送文件
bool sendFile(SOCKET s, const char* fileName)
{
	readFile(fileName);
	int ret = send(s, g_fileBuf, g_fileSzie, 0);
		if (ret == SOCKET_ERROR)
		{
			err("sendFile");
			return false;
		}
	printf("发送成功(%d)Byte\n", ret);
	return true;
}
        4.接收文件
bool recvFile(SOCKET s,const char*fileName)
{
	if (g_fileBuf == NULL)
	{
		g_fileBuf = calloc(g_fileSzie, sizeof(char));
		if (!g_fileBuf)
		{
			return false;
		}
	}

	int ret = recv(s, g_fileBuf, g_fileSzie, 0);
	if (ret == 0)
	{
		printf("下线\n");
	}
	else if (ret < 0)
	{
		err("recv");
	}

	saveFile(fileName);
	return false;
}

        至此,是我们需要用到的文件传输函数,接下来介绍创建套接字以及一些初始化函数。

二,socket初始化         1.初始化网络库
bool init_Socket()//初始化网络库
{
	WSADATA wsadata;
	if(0!=WSAStartup(MAKEWORD(2,2),&wsadata ))//windows异步套接字启动
	{
		printf("[error]WSAStarup failed,code %d\n", WSAGetLastError());
		return false;
	}
	return true;
}
        2.关闭网络库
bool close_Socket()//关闭网络库
{
	if (0!=WSACleanup())
	{
		printf("[error]WSACleanup failed,code %d", WSAGetLastError());
		return false;
	}
	return true;	
}
        3.创建套接字

        以下代码为服务器创建套接字的过程,绑定套接字后需要有一个listen函数来监听我们的客户端是否有请求发到服务器。

SOCKET create_serverSocket()
{
	SOCKET fd=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//创建一个空的socket
	if (INVALID_SOCKET == fd)
	{
		printf("[error]socket failed,code %d", WSAGetLastError());
		return INVALID_SOCKET;
	}
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(PORT);//把本地字节序转换为网络字节序
	addr.sin_addr.S_un.S_addr = ADDR_ANY;//绑定本地任意IP

	if (SOCKET_ERROR == bind(fd,(struct sockaddr *)&addr, sizeof(addr)))
	{
		printf("[error]bind failed,code %d", WSAGetLastError());
		return INVALID_SOCKET;//-1
	}
	listen(fd, 10);

	return fd;
}

        以下代码为客户端创建套接字的过程,不需要绑定bind()函数,也不需要监听。

SOCKET create_clientSocket(const char* ip)
{
	SOCKET fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//创建一个空的socket
	if (INVALID_SOCKET == fd)
	{
		err("socket");
		return INVALID_SOCKET;
	}
	//给socket绑定服务端的ip地址和端口号
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(PORT);//把本地字节序转换为网络字节序
	addr.sin_addr.S_un.S_addr = inet_addr(ip);//绑定服务器任意IP
	if (INVALID_SOCKET == connect(fd, (struct sockaddr*)&addr, sizeof(addr)))
	{
		err("connect");
		return INVALID_SOCKET;
	}

	return fd;
}
三,发送文件         1.server服务端

            新建一个套接字clifd来发送文件,注意在sendFile函数中填入的套接字是accept新建的,而不是初始化用到那个套接字serfd。

int main()
{
 	 //char recvBu[1024] = "今天周几?";
	 init_Socket();
	 SOCKET serfd = create_serverSocket();
	 printf("server create successed,wait client connet....\n ");//
	 SOCKET clifd = accept(serfd, NULL, NULL);
	 if (clifd==INVALID_SOCKET)
	 {
		 printf("[error]accept failed,code %d", WSAGetLastError());
	 }

	 sendFile(clifd,"./server.txt");

	/* if (SOCKET_ERROR== send(clifd, recvBu, strlen(recvBu), 0))
	 {
		 printf("[error]hello send failed,code %d", WSAGetLastError());
	 }*/

	 /*char recvBuf[1024] = "";
	 int ret = recv(clifd, recvBuf, 1024, 0);
	 if (ret == 0)
	 {
		 printf("客户端正常下线下线\n");
	 }
	 else if (ret < 0)
	 {
		 err("recv");
	 }
	 puts(recvBuf);*/

	 closesocket(clifd);
	 closesocket(serfd);
	 close_Socket();

	 return 0;
}
        2.cilent客户端
int main()
{
	init_Socket();

	SOCKET fd = create_clientSocket("127.0.0.1");

	printf("successed\n");

	recvFile(fd, "接收的server文件.txt");

	//char recvBuf[1024] = "";
	//int ret = recv(fd, recvBuf, 1024, 0);
	//if (ret == 0)
	//{
	//	printf("下线\n");
	//}
	//else if(ret<0)
	//{
	//	err("recv");
	//}
	//puts(recvBuf);
	//char sendBuf[1024] = "今天周五";
	//send(fd, sendBuf, strlen(sendBuf), 0);

	closesocket(fd);

	getchar();
	return 0;
}

        至此,文件发送成功,文件在工程文件所在的目录,也可以自己给出完整目录。完整代码如下socket网络通信,传输文件-C文档类资源-CSDN下载

 

 

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/3002723.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-09-27
下一篇 2022-09-27

发表评论

登录后才能评论

评论列表(0条)

保存