####MSG_PEEK 处理粘包问题
ssize_t recv_peek(int sockfd ,void *buf ,size_t len)
{
while(1)
{
int ret = recv(sockfd ,buf,len,MSG_PEEK);
if(ret == -1 && errno == EINTR)
continue;
return ret;
}
}
ssize_t recv_peek(int sockfd ,void *buf ,size_t maxline)
{
int ret;
int nread;
char *bufp = buf;
int nleft = maxline; //一行不能超过maxline
while(1)
{
ret = recv_peek(sockfd,bufp,nleft);
if(ret < 0)
return ret ;
else if(ret == 0) //对方关闭
return ret;
nread = ret;
int i;
for(i=0;i<nread;i++)
{
if(bufp[i] == '\n')
{
ret = readn(sockfd,bufp,i+1);
if(ret != i+1)
exit(EXIT_FAILURE);
return ret;
}
}
if(nread > nleft)
exit(EXIT_FAILURE);
nleft -=nread;
ret = readn(sockfd,bufp,nread);
if(ret != nread)
exit(EXIT_FAILURE);
bufp +=nread;
}
return -1;
}
服务器
char recvbuf[1024];
while(1)
{
memset(recvbuf,0,sizeof(recvbuf));
int ret = readline(conn,recvbuf,1024);
if(ret == -1) ERR_EXIT("readline");
if(ret == 0)
{
printf("client close");
break;
}
//printf recvbuf
writen(conn,recvbuf,strlen(recvbuf));
}
客户端
//
char sendbuf[1024] = {0};
char recvbuf[1024] = {0};
//从标准输入获得发送数据 结尾有\r\n
writen(sock,sendbuf,strlen(sendbuf));
int ret = readline(sock,recvbuf,sizeof(recvbuf));
if(ret == -1) ERR_EXIT("readline");
else if(ret == 0)
{
printf("ser close");
break;
}
//printf
memset(recvbuf,0,sizeof(recvbuf));
getsockname
获得套接口本地地址
int getsockname(int sockfd,struct sockaddr *addr,socklen_t addrlen)
//sock 要是已连接套接口
struct sockaddr_in localaddr;
socklen_t addrlen = sizeof(localaddr);
if( getsockname(sock,(struct sockaddr *)&localaddr,addrlen) < 0)
ERR_EXIT("getsockname");
printf("ip:%s,port:%d",inet_ntoa(localaddr.sin_addr),ntohl(localaddr.sin_port));
getpeername
获得套接口对端地址 用法同上
#####gethostname
获得主机名称
#####gethostbyname
通过主机名称获得ip
char host[100];
if( gethostname(host,sizeof(host)) < 0)
ERR_EXIT("gethostname");
struct hostent *hp;
if((hp = gethostbyname(host)) == NULL)
ERR_EXIT("gethostbyname");
int i=0;
while( hp->h_addr_list[i] != NULL )
{
printf("%s",inet_ntoa(*(struct in_addr *)hp->h_addr_list[i]);
i++;
}