#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
typedef struct
{
int sockfd;
int connfd;
unsigned short tcpPort;
} FAX_INFO_T;
int recv_message(int sockfd, char *buf, int len)
{
int count = 0, ret;
for (; ;)
{
ret = recv(sockfd, buf + count, len - count, 0);
if (ret <= 0) /*出错时,返回<0 即close(sockfd),以后在调用recv会出错*/
{
perror ("recv failed.");
return -1;
}
count += ret;
if (count == len)
{
break;
}
}
return 0;
}
int send_message(int sockfd, char *buf, int len)
{
int count = 0, ret;
for (; ;)
{
ret = send(sockfd, buf + count, len - count, 0);
if (ret <= 0)
{
perror("send failed");
return -1;
}
count += ret;
if (count == len)
{
break;
}
}
return 0;
}
1、初始化TCP套接字
int initFaxTcpSocket()
{
int sockfd;
int iRet, on;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("[%s %d] socket failed.\r\n", __FILE__, __LINE__);
return -1;
}
/* 服务端需设置此项 */
on = 1;
iRet = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
if (iRet < 0)
{
close(sockfd);
printf("[%s %d] setsockopt failed", __FILE__, __LINE__);
return -1;
}
return sockfd;
}
2、服务端处理:等待客户连接处理
int waitClientConnect(FAX_INFO_T *info)
{
int connfd;
int iRet, connFlag = 1;
fd_set fdset;
struct timeval tv;
struct sockaddr_in cliAddr, serAddr;
int iAddrLen = sizeof(struct sockaddr_in);
serAddr.sin_family = AF_INET;
serAddr.sin_addr.s_addr = htonl(INADDR_ANY);
serAddr.sin_port = htons(info->tcpPort);
/* bind */
iRet = bind(info->sockfd, (struct sockaddr *)&serAddr, iAddrLen);
if (iRet != 0)
{
printf("[%s %d][TCP SVR] bind failed.\r\n", __FILE__, __LINE__);
return -1;
}
/* listen */
if (listen(info->sockfd, 1) != 0) /*只允许同时1个客户端连接,即在此端口上只能连接一路传真发送方*/
{
printf("[%s %d] listen failed.\r\n", __FILE__, __LINE__);
return -1;
}
/* vxworks 不知道是否有errno错误值 errno == EINTR*/
/* accept,加select超时,防止客户端在accept之前失去连接,导致该任务一直阻塞于accept*/
FD_ZERO(&fdset);
FD_SET(info->sockfd, &fdset);
tv.tv_sec = 9;
tv.tv_usec = 0;
iRet = select(info->sockfd + 1, &fdset, NULL, NULL, &tv);
if (iRet > 0)
{
/*成功则为非负描述符*/
connfd = accept(info->sockfd, (struct sockaddr *)&cliAddr, &iAddrLen);
if (connfd < 0)
{
printf("[%s %d] accept failed. \r\n", __FILE__, __LINE__);
return -1;
}
else
{
info->connfd = connfd;
printf("[%s %d] accept succ. connfd = %d\r\n", __FILE__, __LINE__, connfd);
return 0;
}
}
else /* == 0 timeout || < 0 error*/
{
printf("[%s %d] select timeout or Failed\r\n", __FILE__, __LINE__);
return -1;
}
}
3、客户端处理:执行connect