几个需要注意的点:read函数阻塞下并不是如想象一般 读取等到满足相应的长度再退出,而是一收到数据就会返回;
想要达到 接收定长数据的效果,需要在阻塞模式下 将flags 置为:MSG_WAITALL;
实现 非阻塞的模式,有两种 方式:
一种是在connect和accept过后进行 1.获取套接字的相关字段,并进行修改,大致如下:
int x; x=fcntl(s,F_GETFL,0); fcntl(s,F_SETFL,x | O_NONBLOCK);
另外一种方法是:将send/recv 的flags置为 :MSG_DOTWAIT
参考:
自己写得demo:
#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 <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <string.h>
#define PORT 8888
int main()
{
int servSock = 0;
struct sockaddr_in clntAddr;
socklen_t clntAddrSize = sizeof(clntAddr); //socklen_t==int
int clntSock;
if((servSock = socket(AF_INET,SOCK_STREAM,0)) == -1) // creat socket
{
printf("socket create failure!\n");
exit(1);
}
else
{
printf("socket create success!\n");
}
struct sockaddr_in servAddr;
memset(&servAddr,0,sizeof(servAddr));
servAddr.sin_family = AF_INET; //IPV4
servAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //IP addr:str--->struct
servAddr.sin_port = htons(PORT); //port format transform
if(bind(servSock, (struct sockaddr *)&servAddr, sizeof(servAddr)) !=0)
{
printf("bind failure!\n");
exit(2);
}
else
{
printf("bind success!\n");
}
if(listen(servSock, 10) != 0)
{
printf("listen failure!\n");
exit(3);
}
else
{
printf("listen...\n");
}
clntSock = accept(servSock, (struct sockaddr*)&clntAddr, &clntAddrSize); //阻塞 clntSock;
if(clntSock <= 0)
{
printf("accept failure!\n");
sleep(1);
}
else
{
printf("accept sucess!\n");
char * msgRcv = (char *)malloc(sizeof(char)*300);
while(1)
{
int n = recv(clntSock,msgRcv,300,MSG_WAITALL);
if(n > 0)
{
//printf("%s,%ld \n",msgRcv,strlen(msgRcv));
printf("%d \n",n);
memset(msgRcv,0,300);
}
else
{
printf("received nothing!\n");
sleep(1);
//break;
}
}
free(msgRcv);
}
close(clntSock);
close(servSock);
return 0;
}
#################################################################
#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 <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <stdint.h>
#define PORT 8888
int main()
{
uint32_t msg[] = {0x01,0x01,0x01,0x01,0x99,0x01,0x01,0x01,0x21,0x41,0x31,0x11,0x01,0x01,0x01,0x01,0x99,0x01,0x01,0x01,0x21,0x41,0x31,0x11,
0x01,0x01,0x01,0x01,0x99,0x01,0x01,0x01,0x21,0x41,0x31,0x11,0x01,0x01,0x01,0x01,0x99,0x01,0x01,0x01,0x21,0x41,0x31,0x11,0x01,0x21,0x01,0x01,0x99,0x01,0x01,0x01,0x21,0x41,0x31,0x11,
0x82,0x01,0x01,0x01,0x21,0x41,0x31,0x11,
0x01,0x01,0x01,0x01,0x99,0x01,0x01,0x01,0x21,0x41,0x31,0x11,0x01,0x01,0x01,0x01,0x99,0x01,0x01,0x01,0x21,0x41,0x31,0x11,0x01,0x21,0x01,0x01,0x99,0x01,0x01,0x01,0x21,0x41,0x31,0x11,0x01,0x01,0x01,0x01,0x99,0x01,0x01,0x01,0x21,0x41,0x31,0x11,0x01,0x01,0x01,0x01,0x99,0x01,0x01,0x01,0x21,0x41,0x31,0x11,
0x01,0x01,0x01,0x01,0x99,0x01,0x01,0x01,0x21,0x41,0x31,0x11,0x01,0x01,0x01,0x01,0x99,0x01,0x01,0x01,0x21,0x41,0x31,0x11,0x01,0x21,0x01,0x01,0x99,0x01,0x01,0x01,0x21,0x41,0x31,0x11,
0x82,0x01,0x01,0x01,0x21,0x41,0x31,0x11,
0x01,0x01,0x01,0x01,0x99,0x01,0x01,0x01,0x21,0x41,0x31,0x11,0x01,0x01,0x01,0x01,0x99,0x01,0x01,0x01,0x21,0x41,0x31,0x11,0x01,0x21,0x01,0x01,0x99,0x01,0x01,0x01,0x21,0x41,0x31,0x11};
char * msgBear =(char*) msg;
int clntSock=socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in serv_addr;
//server IP configuaration
memset(&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
serv_addr.sin_port = htons(PORT);
int len = 0;
int ret = connect(clntSock,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
if(ret < 0)
{
printf("ret = %d,connect error!\n",ret);
}
else
{
while(1)
{
int n = send(clntSock,msgBear,20,MSG_DONTWAIT);
if(n > 0)
{
printf("send bytes %d\n",n);
sleep(1);
}
else
{
printf("send failure!\n");
sleep(1);
//break;
}
}
}
close(clntSock);
return 0;
}