Linux-C 网络编程-TCP应用案例

TCP相关API的介绍: TCP相关API介绍.
本文代码下载地址: tcp案例集合.

案例1.TCP实现读与写

1.write.c(即client)

#include <stdio.h>
#include <sys/types.h>  
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <strings.h>
#include <unistd.h>
#include <string.h>


//./client 192.168.33.3
int main(int argc, const char *argv[])
{
	int skt_fd;
	int retval;
	char buffer[1024];
	ssize_t send_size;
	
	struct sockaddr_in srv_addr;
	
	//步骤1:获取程序通信的套接字(接口)
	skt_fd = socket( AF_INET, SOCK_STREAM, 0);
	if(skt_fd == -1)
	{
		perror("申请套接字失败");
		goto apply_socket_err;
	}
	
	//步骤2:绑定IP地址
	srv_addr.sin_family = AF_INET;//指定引用IPV4的协议

	srv_addr.sin_port = htons(6666);//指定端口号,转化为网络字节序(大端序)

	srv_addr.sin_addr.s_addr = inet_addr(argv[1]);//将所有的IP地址转化为二进制的网络字节序的数据进行绑定	

	//步骤3:发起连接服务器的请求
	retval = connect(skt_fd, (struct sockaddr *)&srv_addr, sizeof(srv_addr));
	if(retval == -1)
	{
		perror("客户端连接到服务器失败\n");
		goto connect_server_err;
	}

	printf("客户端:连接服务器成功\n");

	//发送信息
	while(1)
	{
		scanf("%s", buffer);

		send_size = send( skt_fd, buffer, strlen(buffer), 0);
		if(send_size == -1)
			break;
	}

	close(skt_fd);
	return 0;

apply_socket_err:
connect_server_err:
	close(skt_fd);
	return -1;
}

2.read.c(即server)

#include <stdio.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <strings.h>
#include <unistd.h>

int main(void)
{
	int skt_fd;		//服务端文件描述符
	int retval;		//判断返回值
	char buffer[1024];
	ssize_t recv_size;


	struct sockaddr_in native_addr;
	
	int client_fd;	//客户端文件描述符
	struct sockaddr_in client_addr;
	socklen_t sklen = sizeof(client_addr);

	//步骤1:获取程序通信的套接字(接口)
	skt_fd = socket( AF_INET, SOCK_STREAM, 0);
	if(skt_fd == -1)
	{
		perror("申请套接字失败");
		goto apply_socket_err;
	}

	//步骤2:绑定IP地址
	native_addr.sin_family = AF_INET;//指定引用IPV4的协议

	native_addr.sin_port = htons(6666);//指定端口号,转化为网络字节序(大端序)

	native_addr.sin_addr.s_addr = htonl(INADDR_ANY);//将所有的IP地址转化为二进制的网络字节序的数据进行绑定

	
	//步骤3:将指定的地址信息及本程序的套接字绑定在一起
	retval = bind( skt_fd, (struct sockaddr *)&native_addr, sizeof(native_addr));
	if(retval == -1)
	{
		perror("绑定套接字地址失败");
		goto bind_socket_err;
	}


	//步骤4:设置监听,最多可连接50个客户端
	retval = listen(skt_fd, 50);
	if(retval == -1)
	{
		perror("设置最大连接数失败");
		goto set_listen_err;
	}

	//步骤5:等待客户端链接,链接成功后返回一个代表客户端通信的文件描述符,具备阻塞特性
	client_fd = accept(skt_fd, (struct sockaddr *)&client_addr, &sklen);
	if(client_fd == -1)
	{
		perror("客户端链接失败");
		goto client_connect_err;
	}

	printf("服务器:客户端连接成功\n");
	printf("客户端信息:\n客户端IP为%s,端口号为%hu\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

	//接收消息
	while(1)
	{
		bzero(buffer, sizeof(buffer));

		//接受来自与客户端的数据,这个接受具备阻塞特性,同read
		recv_size = recv(client_fd, buffer, sizeof(buffer), 0);
		if(recv_size == -1)
		{
			perror("接受数据异常");
			goto socket_recv_err;
		}
		
		else if(recv_size == 0)//代表客户端断开连接
			break;

		printf("接收到来自与客户端%ld个字节的数据:%s\n", recv_size, buffer);
	}

	close(client_fd);//关闭客户端通信
	close(skt_fd);//关闭服务器的socket资源

	return 0;

socket_recv_err:
	close(client_fd);

apply_socket_err:
client_connect_err:
set_listen_err:
bind_socket_err:
	close(skt_fd);
	return -1;
}

案例2.TCP多线程实现双向通信

1.server.c

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h> 
#include <pthread.h>
 

 struct msg_buf{
	 char name[16];
	 char buf[1024];
	 
 };
 
//接收线程所要执行的函数 接收消息
void * recv_msg(void *arg)
{
	struct msg_buf msg;
	int client_fd = *(int *)arg;//通信的socket
	ssize_t recv_size;

	while(1)
	{
		//char buf[1024];
		bzero(&msg, sizeof(msg));
		//recv_size = recv(client_fd, &msg, sizeof(msg), 0);
		recv_size = read(client_fd, &msg, sizeof(msg));
		if(recv_size == -1)
		{
			perror("接受数据异常");
			break;
		}
		else if(strncmp(msg.buf, "exit", 4) == 0 || strcmp(msg.buf, "") == 0)
		{
			
			break;//退出
		}
		
		printf("%s的新的消息:\n%s\n", msg.name, msg.buf);
	}
	return NULL;
}
 
 //  ./server 名字
int main(int argc, char **argv)
{
	int retval;
	int socket_fd;
	struct msg_buf msg;	
	struct sockaddr_in client_addr;
	int len = sizeof(client_addr);
	int client_fd;
	pthread_t pid;
	size_t send_size;
	
	
	//1 创建tcp通信socket
	socket_fd = socket(AF_INET, SOCK_STREAM, 0);
	if(socket_fd == -1)
	{
		perror("申请套接字失败!\n");
		goto get_socket_fd_err;
	}
	
	//2 绑定socket地址
	struct sockaddr_in server_addr;
	
	server_addr.sin_family = AF_INET;//指定引用IPV4的协议
	
	server_addr.sin_port = htons(6666);//指定端口号,转化为网络字节序(大端序)
	
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//指定端口号,转化为网络字节序(大端序)
	
	//3 将指定的地址信息及本程序的套接字绑定在一起
	retval = bind(socket_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
	if(retval == -1)
	{
		perror("绑定套接字地址失败!\n");
		goto bind_socket_err;
	}
 
	//4 设置监听,最多可连接50个客户端
	retval = listen(socket_fd, 50);
	if(retval == -1)
	{
		perror("设置最大连接数失败!\n");
		goto listen_client_err;
	}
	
	//5 等待客户端连接
	client_fd = accept( socket_fd, (struct sockaddr *)&client_addr, &len);
	if(client_fd == -1)
	{
		perror("客户端链接失败!\n");
		goto accept_client_err;
	}
	
	printf("服务器:客户端连接成功,开始聊天,输入‘exit’退出聊天\n");
	printf("客户端IP为%s,端口号为%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
 
		
	retval = pthread_create(&pid, NULL, recv_msg, (void*)&client_fd);
	if(retval != 0)
	{
		printf("开启线程失败\n");
		goto creat_pthread_err;
	}
	strcpy (msg.name, argv[1]);
	while(1)
	{
		scanf("%s", msg.buf);
		
		//send_size = send( client_fd, buf, strlen(buf), 0);
		send_size = write(client_fd, &msg, sizeof(msg));//发送消息
		
		if(strcmp(msg.buf, "exit") == 0 || strcmp(msg.buf, "") == 0)
		{
			retval = pthread_cancel(pid);//取消线程
			break;
		}

	}
 
	//5 关闭通信socket
	close(client_fd);
	close(socket_fd);
 
	return 0;
	
accept_client_err:
creat_pthread_err:
listen_client_err:
bind_socket_err:
get_socket_fd_err:
	return -1;
}

2.client.c

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h> 
#include <pthread.h>
 
struct msg_buf{
	char name[16];
	char buf[1024];
	 
 };
 
//接收线程所要执行的函数 接收消息
void * recv_msg(void *arg)
{
	struct msg_buf msg;
	int client_fd = *(int *)arg;//通信的socket
	ssize_t recv_size;

	char buf[1024];
	while(1)
	{
		bzero(&msg, sizeof(msg));
		//recv_size = recv(client_fd, &msg, sizeof(msg), 0);
		recv_size = read(client_fd, &msg, sizeof(msg));
		
		if(recv_size == -1)
		{
			perror("接受数据异常");
			break;
		}
		else if(strncmp(msg.buf, "exit", 4) == 0 || strcmp(msg.buf, "") == 0)
		{
			
			break;//退出
		}
		
		printf("%s的新的消息:\n %s\n", msg.name, msg.buf);
	}
	return NULL;
}
 
 //  ./server IP 名字
int main(int argc, char **argv)
{
	int retval;
	int socket_fd;
	struct msg_buf msg;	
	struct sockaddr_in client_addr;
	int len = sizeof(client_addr);
	char buf[1024];
	pthread_t pid;
	size_t send_size;
	
	
	//1 创建tcp通信socket
	socket_fd = socket(AF_INET, SOCK_STREAM, 0);
	if(socket_fd == -1)
	{
		perror("申请套接字失败!\n");
		goto get_socket_fd_err;
	}
	
	//2 绑定socket地址
	struct sockaddr_in server_addr;
	
	server_addr.sin_family = AF_INET;//指定引用IPV4的协议
	
	server_addr.sin_port = htons(6666);//指定端口号,转化为网络字节序(大端序)
	
	server_addr.sin_addr.s_addr = inet_addr(argv[1]);//指定端口号,转化为网络字节序(大端序)
	
	//3:发起连接服务器的请求
	retval = connect(socket_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
	if(retval == -1)
	{
		perror("客户端连接到服务器失败\n");
		goto connect_server_err;
	}

	printf("客户端:连接服务器成功,开始聊天,输入‘exit’退出聊天\n");

	retval = pthread_create(&pid, NULL, recv_msg, (void*)&socket_fd);
	if(retval != 0)
	{
		printf("开启线程失败\n");
		goto creat_pthread_err;
	}
	
	strcpy (msg.name, argv[2]);
	while(1)
	{
		scanf("%s", msg.buf);
		
		//send_size = send( socket_fd, buf, strlen(buf), 0);
		send_size = write(socket_fd, &msg, sizeof(msg));//发送消息
		
		if(strcmp(msg.buf, "exit") == 0 || strcmp(msg.buf, "") == 0)
		{
			retval = pthread_cancel(pid);//取消线程
			
			break;
		}

	}
 
	//5 关闭通信socket
	//close(client_fd);
	close(socket_fd);
 
	return 0;
	
get_socket_fd_err:
creat_pthread_err:
connect_server_err:
	return -1;
}

案例3.TCP多路复用监控多个文件描述符

select.c

#include <stdio.h>
#include <sys/types.h>     
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <strings.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
       
int main(void)
{
	int skt_fd;
	int retval;

	skt_fd = socket( AF_INET, SOCK_STREAM, 0);
	if(skt_fd == -1)
	{
		perror("申请套接字失败");
		return -1;
	}


	struct sockaddr_in native_addr;

	native_addr.sin_family = AF_INET;//指定引用IPV4的协议

	native_addr.sin_port = htons(6666);//指定端口号,转化为网络字节序(大端序)

	native_addr.sin_addr.s_addr = htonl(INADDR_ANY);//将所有的IP地址转化为二进制的网络字节序的数据进行绑定

	retval = bind( skt_fd, (struct sockaddr *)&native_addr, sizeof(native_addr));
	if(retval == -1)
	{
		perror("绑定套接字地址失败");
		goto bind_socket_err;
	}

	retval = listen(skt_fd, 50);
	if(retval == -1)
	{
		perror("设置最大连接数失败");
		goto set_listen_err;
	}
	
	int max_fd = skt_fd;//拿到要操作的文件描述符中最大文件描述符
	fd_set read_fd_set;//读文件描述符集合

	int client_fd;
	struct sockaddr_in client_addr;
	socklen_t sklen = sizeof(client_addr);
	

	printf("start listen network\n");

	char buffer[1024];

	while(1)
	{
		FD_ZERO(&read_fd_set);//清空一下文件描述符集合
		FD_SET(skt_fd, &read_fd_set);
		FD_SET( 0, &read_fd_set);
		
		/*最新创建的文件描述符即为最大文件描述符
			max_fd+1:要监控的最大的文件描述符值+1
			&read_fd_set:读文件描述符集合
			NULL, NULL, NULL:分别代表写文件描述符集合,其他类型文件描述符集合,时间参数结构体		
		*/
		retval = select(max_fd+1, &read_fd_set, NULL, NULL, NULL);//这个函数将会在这里阻塞,一直等到我们我监听的文件描述符有动静才会被唤醒
		if(retval == -1)
		{
			perror("监听异常");
			goto select_err;
		}else if(retval)
		{
			//判断文件描述符是不是在这个集合里面,如果还存在在这个集合里面则证明是skt_fd这个文件描述符唤醒的我们
			if(FD_ISSET(skt_fd, &read_fd_set))
			{
				client_fd = accept(skt_fd, (struct sockaddr *)&client_addr, &sklen);
				if(client_fd == -1)
				{
					perror("客户端链接失败");
					goto client_connect_err;
				}

				printf("服务器:客户端连接成功\n");
				printf("客户端信息:\n客户端IP为%s,端口号为%hu\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
			}
			else if(FD_ISSET(0, &read_fd_set))
			{
				read(0, buffer, sizeof(buffer));
				printf("从键盘中读取到的数据为%s\n", buffer);
			}
			 
		}else
			break;
	}
	return 0;

socket_recv_err:
	close(client_fd);
client_connect_err:

select_err:
set_listen_err:
bind_socket_err:
	close(skt_fd);
	return -1;
}

client.c

//可使用案例二的client.c
//用法  ./client 192.168.32.111

案例4.TCP多路复用实现多人聊天室

server.c

//思路:select接收到的客户端信息插入链表,遍历链表打印收到的信息,客户端实现读写
#include <stdio.h>
#include <sys/types.h>   
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <strings.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#define	list_for_each(head, pos)\
	for(pos=head->next; pos!=NULL; pos=pos->next)

typedef struct client_info{
	int client_fd;
	char name[256];
	char ip[16];
	short port;
	pthread_t tid;

	struct client_info *next;
}client_info_node;

//申请客户端信息链表的头节点
static client_info_node *request_client_info_node(const client_info_node *info)
{
	client_info_node *new_node;

	new_node = malloc(sizeof(client_info_node));
	if(new_node == NULL)
	{
		perror("申请客户端节点异常");
		return NULL;
	}

	if(info != NULL)
		*new_node = *info;

	new_node->next = NULL;

	return 	new_node;
}

static inline void insert_client_info_node_to_link_list(client_info_node *head, client_info_node *insert_node)
{
	client_info_node *pos;

	for(pos=head; pos->next != NULL; pos=pos->next);

	pos->next = insert_node;
}


void *client_thread(void *arg)
{
	int client_fd;
	char buffer[1024];
	ssize_t recv_size, send_size;
	client_info_node *pos, *list_head = arg;
	
	list_for_each(list_head, pos)
	{
		if(pthread_self() == pos->tid)
		{
			client_fd = pos->client_fd;
			break;
		}
	}

	while(1)
	{
		bzero(buffer, sizeof(buffer));

		recv_size = recv(client_fd, buffer, sizeof(buffer), 0);
		if(recv_size == -1)
		{
			perror("接受数据异常");
			break;
		}
		else if(recv_size == 0)//代表客户端断开连接
		{
			//删除链表节点
			break;
		}

		list_for_each(list_head, pos)
		{
			if(pos->client_fd == client_fd)
				continue;

			printf("转发数据给端口号为%hu\n", pos->port);

			send_size = send( pos->client_fd, buffer, recv_size, 0);
			if(send_size == -1)
				break;
		}
		printf("接收到来自与客户端%ld个字节的数据:%s\n", recv_size, buffer);
	}


	return NULL;
}

int main(void)
{
	int skt_fd;
	int retval;
	client_info_node *list_head, *new_node;
	client_info_node cache_client_info;

	list_head = request_client_info_node(NULL);

	skt_fd = socket( AF_INET, SOCK_STREAM, 0);
	if(skt_fd == -1)
	{
		perror("申请套接字失败");
		return -1;
	}


	struct sockaddr_in native_addr;

	native_addr.sin_family = AF_INET;//指定引用IPV4的协议

	native_addr.sin_port = htons(6666);//指定端口号,转化为网络字节序(大端序)

	native_addr.sin_addr.s_addr = htonl(INADDR_ANY);//将所有的IP地址转化为二进制的网络字节序的数据进行绑定

	
	retval = bind( skt_fd, (struct sockaddr *)&native_addr, sizeof(native_addr));
	if(retval == -1)
	{
		perror("绑定套接字地址失败");
		goto bind_socket_err;
	}


	/*
		设置套接字的同时通信最大连接数为50,并且将这个套接字的属性设置为可监听属性
	*/
	retval = listen(skt_fd, 50);
	if(retval == -1)
	{
		perror("设置最大连接数失败");
		goto set_listen_err;
	}

	int client_fd;
	struct sockaddr_in client_addr;
	socklen_t sklen = sizeof(client_addr);

	while(1)
	{


		cache_client_info.client_fd = accept(skt_fd, (struct sockaddr *)&client_addr, &sklen);
		if(cache_client_info.client_fd == -1)
		{
			perror("客户端链接失败");
			goto client_connect_err;
		}

		strcpy(cache_client_info.ip, inet_ntoa(client_addr.sin_addr));//存放IP地址
		cache_client_info.port = ntohs(client_addr.sin_port);

		//新建节点
		new_node = request_client_info_node(&cache_client_info);
		//将节点插入链表
		insert_client_info_node_to_link_list(list_head, new_node);


		printf("服务器:客户端连接成功\n");
		printf("客户端信息:\n客户端IP为%s,端口号为%hu\n", cache_client_info.ip, cache_client_info.port);

		pthread_create(&(new_node->tid), NULL, client_thread, list_head);

	}

	close(client_fd);//关闭客户端通信
	close(skt_fd);//关闭服务器的socket资源

	return 0;

socket_recv_err:
	close(client_fd);
client_connect_err:
set_listen_err:
bind_socket_err:
	close(skt_fd);
	return -1;
}

client.c

//可用案例二client.c
//用法  ./client 192.168.32.111

案例5.TCP服务端向客户端发送文件

server.c

#include <stdio.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <strings.h>
#include <unistd.h>
 #include <string.h>


//./server
int main(void)
{
	int skt_fd;
	int retval;

	skt_fd = socket( AF_INET, SOCK_STREAM, 0);
	if(skt_fd == -1)
	{
		perror("申请套接字失败");
		return -1;
	}


	struct sockaddr_in native_addr;

	native_addr.sin_family = AF_INET;//指定引用IPV4的协议

	native_addr.sin_port = htons(7777);//指定端口号,转化为网络字节序(大端序)


	native_addr.sin_addr.s_addr = htonl(INADDR_ANY);//将所有的IP地址转化为二进制的网络字节序的数据进行绑定

	
	retval = bind( skt_fd, (struct sockaddr *)&native_addr, sizeof(native_addr));
	if(retval == -1)
	{
		perror("绑定套接字地址失败");
		goto bind_socket_err;
	}

	retval = listen(skt_fd, 1);
	if(retval == -1)
	{
		perror("设置最大连接数失败");
		goto set_listen_err;
	}

	int client_fd;
	struct sockaddr_in client_addr;
	socklen_t sklen = sizeof(client_addr);


	client_fd = accept(skt_fd, (struct sockaddr *)&client_addr, &sklen);
	if(client_fd == -1)
	{
		perror("客户端链接失败");
		goto client_connect_err;
	}

	printf("服务器:客户端连接成功\n");
	//printf("客户端信息:\n客户端IP为%s,端口号为%hu\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

	char buffer[1024];
	ssize_t recv_size;



	bzero(buffer, 1024); 


	// 然后从buffer(缓冲区)拷贝到file_name中 
	char file_name[512+1]; 
	bzero(file_name, 512+1); 
	
	printf("请输入一个文件名字:\t"); 
	scanf("%s", file_name); 
	
	bzero(buffer, sizeof(buffer)); 
	strncpy(buffer, file_name, strlen(file_name)>1024?1024:strlen(file_name)); 

	// 向服务器发送buffer中的数据 
	if(send(client_fd, buffer, 1024, 0) < 0) 
	{ 
		perror("文件写入失败:"); 
		return -1;
	} 
	

	// 打开文件并读取文件数据 
	FILE *fp = fopen(file_name, "r"); 
	if(NULL == fp) 
	{ 
		printf("文件%s 不存在\n", file_name); 
		return -1;
	} 
	else 
	{ 
		bzero(buffer, 1024); 
		int length = 0; 
		// 读取1024数据,将其发送给客户端,循环直到文件读完为止 
		while((length = fread(buffer, sizeof(char), 1024, fp)) > 0) 
		{ 
			if(send(client_fd, buffer, length, 0) < 0) 
			{ 
				printf("发送文件%s 失败./n", file_name); 
				break; 
			} 
		bzero(buffer, 1024); 
		} 

	  // 关闭文件 
	  fclose(fp); 
	  printf("文件%s 传输失败!\n", file_name); 
	} 

	close(skt_fd);
	close(client_fd);

	return 0;

socket_recv_err:
	close(client_fd);
client_connect_err:
set_listen_err:
bind_socket_err:
	close(skt_fd);
	return -1;
}

client.c

#include <stdio.h>
#include <sys/types.h>    
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <strings.h>
#include <unistd.h>
#include <string.h>


//./client
int main(int argc, const char *argv[])
{
	int skt_fd;
	int retval;

	/*
		获取程序通信的套接字(接口)
		AF_INET:IPV4的协议
		SOCK_STREAM:指定TCP协议
		0:代表不变化协议内部(ip手册中指定的参数)
	*/
	skt_fd = socket( AF_INET, SOCK_STREAM, 0);
	if(skt_fd == -1)
	{
		perror("申请套接字失败");
		return -1;
	}

	struct sockaddr_in srv_addr;

	srv_addr.sin_family = AF_INET;//指定引用IPV4的协议

	srv_addr.sin_port = htons(7777);//指定端口号,转化为网络字节序(大端序)

	//将所有的IP地址转化为二进制的网络字节序的数据进行绑定,根据项目的需求传入所需的IP
	srv_addr.sin_addr.s_addr = inet_addr("192.168.32.116");

	retval = connect(skt_fd, (struct sockaddr *)&srv_addr, sizeof(srv_addr));
	if(retval == -1)
	{
		perror("客户端连接到服务器失败\n");
		goto connect_server_err;
	}

	printf("客户端:连接服务器成功\n");

	char buffer[1024]; 
	char file_name[1024+1]; 
	bzero(file_name, 1024+1); 
	
	if(recv(skt_fd, buffer, 1024, 0) < 0) 
		{ 
			perror("Server Recieve Data Failed:"); 
			return -1;
		}
	
	strncpy(file_name, buffer, strlen(buffer)>512?512:strlen(buffer)); 
	printf("%s\n", file_name); 

	// 打开文件,准备写入 
	FILE *fp = fopen(file_name, "w"); 
	if(NULL == fp) 
	{ 
		perror("无法打开文件\n"); 
		return -1; 
	} 

	// 从服务器接收数据到buffer中 
	// 每接收一段数据,便将其写入文件中,循环直到文件接收完并写完为止 
	bzero(buffer, 1024); 
	int length = 0; 
	while((length = recv(skt_fd, buffer, 1024, 0)) > 0) 
	{ 
		if(fwrite(buffer, sizeof(char), length, fp) < length) 
		{ 
			perror("写入失败\n"); 
			break; 
		} 
		bzero(buffer, 1024); 
	} 

	// 接收成功后,关闭文件,关闭socket 
	printf("接受文件:\t%s 成功!\n", file_name); 
	fclose(fp); 

	
	

	close(skt_fd);

	return 0;


connect_server_err:
	close(skt_fd);
	return -1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值