Socket编程:解决发送与接收数据不全

这个问题是在上个月在做的项目中遇到的问题。项目采用分布式计算,通过网线传输数据。然而却发现用Socket接收和发送数据会出现不全的问题。由于是第一次使用Socket,因此这个问题还是费了点时间去解决。现在把它整理下。


客户端
原来的编程方案:(错误)

//创建套接字
int sock = socket(AF_INET, SOCK_STREAM, 0);
//向服务器(特定的IP和端口)发起请求
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));  //每个字节都用0填充
serv_addr.sin_family = AF_INET;  //使用IPv4地址
serv_addr.sin_addr.s_addr = inet_addr("169.254.48.205");  //具体的IP地址
serv_addr.sin_port = htons(1234);  //端口
connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
//向服务器发送数据
printf("Sending...\n");
write(sock, (char*)conv_ouput, sizeof(float) * 25088);
printf("Send Successful\n");
//关闭套接字
close(sock);

这里有个问题,即是发送端不能保证一次性全部发完数据。因此必须确保发送到能够发全数据。

修改后的编程方案:(正确)

int sock = socket(AF_INET, SOCK_STREAM, 0);
//向服务器(特定的IP和端口)发起请求
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));  //每个字节都用0填充
serv_addr.sin_family = AF_INET;  //使用IPv4地址
serv_addr.sin_addr.s_addr = inet_addr("169.254.48.205");  //具体的IP地址
serv_addr.sin_port = htons(1234);  //端口
connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
//向服务器发送数据
printf("Sending...\n");
int pos = 0;
while(pos < 25088*sizeof(float))
{
	int send_num = send(sock,(char*)conv_ouput+pos, sizeof(float) * 25088, 0);
	if(send_num<=0)
	{
		break;
		printf("send error\n");
	}
	pos += send_num;
}
printf("send num = %d\n",pos);
printf("Send Successful\n");
//关闭套接字
close(sock);

服务端:
原来的编程方案:(错误)

//接收客户端请求
struct sockaddr_in clnt_addr;
socklen_t clnt_addr_size = sizeof(clnt_addr);
int clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);
printf("Accept sock create Successful\n");

//接收客户传回的数据
float szBuffer[25088] = { 0 };
read(clnt_sock, (char*)szBuffer, sizeof(szBuffer));
i = i + 1;
run_fc(szBuffer);
close(clnt_sock);

同样的问题,服务端不能保证一次性全部接收完所有数据。因此同样要加个判断循环。

修改后的编程方案:(正确)

//接收客户端请求
struct sockaddr_in clnt_addr;
socklen_t clnt_addr_size = sizeof(clnt_addr);
int clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);
printf("Accept sock create Successful\n");

//接收客户传回的数据
float *szBuffer = new float[25088];
int pos = 0;
while(pos < 25088*sizeof(float))
{
	int rec_num = recv(clnt_sock, (char*)szBuffer+pos, sizeof(float)*25088, 0);
	if(rec_num<=0)
	{
		break;
		printf("send error\n");
	}
	pos += rec_num;
}
i = i + 1;
run_fc(szBuffer);
close(clnt_sock);

其实学会了也很简单。

发表评论

电子邮件地址不会被公开。 必填项已用*标注