Linux C Socket传结构

服务端:

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

#define IPADDRESS "127.0.0.1"
#define PORT 5174
#define DATASIZE 6000000 * sizeof(int)
#define RECV_BUF_SIZE 1024
#define SEND_BUF_SIZE 1024

#define ARRAY_POS1 DATASIZE / sizeof(int) / 2
#define ARRAY_POS2 DATASIZE / sizeof(int) - 1

#define DEBUG 0
typedef struct send_data{
	void *data;
}send_data_t;

typedef struct client_socket_info{
	int cfd;
	struct sockaddr_in client_addr;
	int num;
}client_info;

void print_error(const char *msg)
{
	perror(msg);
	exit(1);
}

/*线程处理函数*/
void *dispose_client(void *arg)
{
	puts("------此程序演示将客户端发过来的数据+1回传-----");
	client_info *info = (client_info *)arg;
	
	char ipbuf[INET_ADDRSTRLEN];

	bzero(ipbuf,INET_ADDRSTRLEN);

	inet_ntop(AF_INET,&info->client_addr.sin_addr.s_addr,
			ipbuf,INET_ADDRSTRLEN);

	int port = ntohs(info->client_addr.sin_port);

	printf("ID:%d,IP:%s,PROT:%d,ARRAY_SIZE:%ld连接到服务端\n",info->num,ipbuf,port,DATASIZE / sizeof(int));
	
	send_data_t mydata;
	mydata.data = (int *)malloc(DATASIZE);
	if (!mydata.data)
	{
		print_error("mydata.data malloc memory failed\n");
	}

	char *recv_buf = (char *)malloc(DATASIZE);
	if (!recv_buf)
	{
		print_error("recv_buf malloc memory failed\n");
	}
	while(1)
	{
		bzero(recv_buf,DATASIZE);
		bzero(mydata.data,DATASIZE);
		int recv_len,recv_pos = 0;

		while(recv_pos < DATASIZE)
		{
			recv_len = recv(info->cfd,recv_buf + recv_pos,RECV_BUF_SIZE,0);
			if (recv_len <= 0)
				break;
			recv_pos += recv_len;
		}
#if DEBUG	
		printf("recv_len %d,recv_pos %d\n",recv_len,recv_pos);
#endif
		if (!recv_len)
		{
			fprintf(stderr,"客户端[%s:%d]关闭了连接\n\n",ipbuf,port);
			break;
		}
		else if (recv_len < 0)
		{
			fprintf(stderr,"接收客户端[%s:%d]数据失败\n\n",ipbuf,port);
			break;
		}

		memcpy(mydata.data,recv_buf,DATASIZE);

		int *p1 = &((int *)(mydata.data))[ARRAY_POS1],
		*p2 = &((int *)(mydata.data))[ARRAY_POS2];

		printf("客户端[%s:%d]数据:mydata.data[%ld] = %d mydata.data[%ld] = %d\n",
				ipbuf,port,ARRAY_POS1,*p1,ARRAY_POS2,*p2);

		*p1 +=1;
		*p2 +=1;
		int send_len,send_pos = 0;
		char *send_buf = (char *)mydata.data;
		while(send_pos < DATASIZE)
		{
			if ((DATASIZE - send_pos) < SEND_BUF_SIZE)
				send_len = send(info->cfd,send_buf + send_pos,DATASIZE - send_pos,0);
			else
				send_len = send(info->cfd,send_buf + send_pos,SEND_BUF_SIZE,0);

			if (send_len < 0)
			{
				printf("%s:send failed\n",__FUNCTION__);
				break;
			}
			send_pos += send_len;
		}
		printf("服务端处理过的数据:mydata.data[%ld] = %d,mydata.data[%ld] = %d\n\n",ARRAY_POS1,*p1,ARRAY_POS2,*p2);
#if DEBUG
		printf("send_len %d,send_pos %d\n",send_len,send_pos);
#endif
		if (send_len < 0)
		{
			printf("发送到客户端[%s:%d]失败\n",ipbuf,port);
			break;
		}
	}

	close(info->cfd);
	free(info),free(mydata.data),free(recv_buf);
	info = mydata.data = recv_buf = NULL;
	return NULL;
}

int main(int argc,char **argv)
{
	/*初始化socket*/
	int sfd = socket(AF_INET,SOCK_STREAM,0);
	if (sfd == -1)
	{
		print_error("初始化socket失败\n");
	}
	
	/*设置端口复用*/
	int opt = 1;
	setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
	
	/*初始化服务端地址簇*/
	struct sockaddr_in serv_addr;
	bzero(&serv_addr,sizeof(serv_addr));
	serv_addr.sin_addr.s_addr = inet_addr(IPADDRESS);
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(PORT);
	
	/*绑定*/
	int ret = bind(sfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
	if (ret == -1)
	{
		print_error("bing失败\n");
	}
	
	/*监听*/
	ret = listen(sfd,128);
	if (ret == -1)
	{
		print_error("监听失败\n");
	}

	printf("正在监听本机的%d端口\n",PORT);
	
	int i = 0;
	while(1)
	{
		struct sockaddr_in client_addr;
		bzero(&client_addr,sizeof(client_addr));
		socklen_t addrlen = sizeof(client_addr);
		
		/*接受服务端连接*/
		int client_fd = accept(sfd,(struct sockaddr *)&client_addr,&addrlen);
		if (client_fd == -1)
		{
			printf("accept 失败,原因:%s",strerror(errno));
			break;
		}

		/*将客户端信息保存到client_info结构体中*/
		client_info *info = (client_info *)malloc(sizeof(client_info));						
		info->cfd = client_fd;
		memcpy(&info->client_addr,&client_addr,sizeof(client_addr));
		info->num = i++;
		
		/*创建线程*/
		pthread_t id;
		pthread_create(&id,NULL,(void *)dispose_client,(void *)info);

		/*设置线程分离*/
		pthread_detach(id);
	}
	return 0;
}

客户端:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>

#define PORT 5174
#define IPADDRESS "127.0.0.1"

/*接收1024bytes*/
#define RECV_BUF_SIZE 1024

/*发送1024bytes*/
#define SEND_BUF_SIZE 1024

/*数组大小*/
#define DATASIZE 6000000 * sizeof(int)

/*数组下标*/
#define ARRAY_POS1 DATASIZE / sizeof(int) / 2
#define ARRAY_POS2 DATASIZE / sizeof(int) - 1

/*非0为调试*/
#define DEBUG 0

/*客户端发送给服务端时间间隔*/
#define TIME_DELAY 2

typedef struct send_data{
	void *data;
}send_data_t;

void print_error(const char *msg)
{
	printf("%s",msg);
	exit(1);
}

int main(int argc,char **argv)
{
	int sfd = socket(AF_INET,SOCK_STREAM,0);
	if (sfd == -1)
	{
		print_error("init socket failed\n");
	}

	struct sockaddr_in serv_addr;
	bzero(&serv_addr,sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(PORT);
	serv_addr.sin_addr.s_addr = inet_addr(IPADDRESS);
	
	int ret = connect(sfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
	if (ret == -1)
	{
		print_error("connect failed\n");
	}

	printf("已经连接到%s:%d,现在可以向服务器发送消息了!\n",IPADDRESS,PORT);
	
	send_data_t mydata;
	mydata.data = (int *)malloc(DATASIZE);
	if (!mydata.data)
	{
		print_error("mydata.data malloc memory failed\n");
	}
	
	bzero(mydata.data,DATASIZE);
	((int *)(mydata.data))[ARRAY_POS1] = 1024;
	((int *)(mydata.data))[ARRAY_POS2] = 2048;
	
	char *send_buf = (char *)malloc(DATASIZE);
	if(!send_buf)
	{
		print_error("send_buf malloc failed\n");
	}
	memcpy(send_buf,mydata.data,DATASIZE);
	while(1)
	{
		int send_len,send_pos = 0;

		while(send_pos < DATASIZE)
		{
			/*此处为发送数据核心,如果写错将会导致接收方内存越界*/
			if ((DATASIZE - send_pos) < SEND_BUF_SIZE)
				send_len = send(sfd,send_buf + send_pos,DATASIZE - send_pos,0);
			else
				send_len = send(sfd,send_buf + send_pos,SEND_BUF_SIZE,0);

			if (send_len < 0)
			{
				printf("%s send failed\n",__FUNCTION__);
				break;
			}
			send_pos += send_len;
		}

		int *p1 = &((int *)(mydata.data))[ARRAY_POS1];
		int *p2 = &((int *)(mydata.data))[ARRAY_POS2];
		printf("发送到服务端的数据:mydata.data[%ld] %d,mydata.data[%ld] %d\n",ARRAY_POS1,*p1,ARRAY_POS2,*p2);
#if DEBUG
		printf("send_len %d,send_pos %d\n",send_len,send_pos);
#endif
		if (send_len < 0)
		{
			puts("发送到服务器失败");
			break;
		}
		int recv_len,recv_pos = 0;
		bzero(send_buf,DATASIZE);
		char *recv_buf = send_buf;
		while(recv_pos < DATASIZE)
		{
			recv_len = recv(sfd,recv_buf + recv_pos,RECV_BUF_SIZE,0);
			if(recv_len <= 0)
			{
				printf("%s recv failed\n",__FUNCTION__);
				break;
			}
			recv_pos+=recv_len;
		}
#if DEBUG	
		printf("recv_len %d,recv_pos %d\n",recv_len,recv_pos);
#endif
		if(recv_len < 0)
		{
			puts("接收服务器数据失败");
			break;
		}
		memcpy(mydata.data,recv_buf,DATASIZE);

		p1 = &((int *)(mydata.data))[ARRAY_POS1];
		p2 = &((int *)(mydata.data))[ARRAY_POS2];
		printf("服务端处理过的数据:mydata.data[%ld] %d,mydata.data[%ld] %d\n\n",ARRAY_POS1,*p1,ARRAY_POS2,*p2);
		sleep(TIME_DELAY);
	}
	free(mydata.data);
	free(send_buf);
	mydata.data = send_buf = NULL;
	close(sfd);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值