介绍
C Liunx实现EchoServer非阻塞客户端(TPC协议)
服务端在:http://t.csdnimg.cn/5oJfI
支持库
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdbool.h>
代码
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdbool.h>
typedef struct EchoClientInfo
{
int socketFD;
struct sockaddr_in serverAddr;
int bufferSize;
struct timeval timeout;
bool block;
} EchoClient;
EchoClient *InitClient();
int ConnectServer(EchoClient *client, char *ip, int port, bool noBlock);
int SendServerDate(EchoClient *client, char *date);
char *GetServerDate(EchoClient *client);
void CloseConnect(EchoClient *client);
void SetClientTimeout(EchoClient *client, int s, int us);
void FreeClient(EchoClient *client);
EchoClient *InitClient()
{
EchoClient *result = (EchoClient *)malloc(sizeof(EchoClient));
if (result != NULL)
{
memset(result, 0, sizeof(EchoClient));
result->socketFD = 0;
result->bufferSize = 1024;
SetClientTimeout(result, 3, 0);
}
return result;
return result;
}
int ConnectServer(EchoClient *client, char *ip, int port, bool noBlock)
{
struct timeval timeout = client->timeout;
int nRet,ret;
client->socketFD = socket(AF_INET, SOCK_STREAM, 0);
if (client->socketFD < 0)
return -2;
if (noBlock)
{
int flags = fcntl(client->socketFD, F_GETFL, 0);
fcntl(client->socketFD, F_SETFL, flags | O_NONBLOCK);
}
client->block = !noBlock;
client->serverAddr.sin_family = AF_INET;
inet_pton(AF_INET, ip, &client->serverAddr.sin_addr);
client->serverAddr.sin_port = htons(port);
ret = connect(client->socketFD, (struct sockaddr *)&client->serverAddr, sizeof(client->serverAddr));
if (client->block && ret == 0)
goto Success;
fd_set wait;
FD_ZERO(&wait);
FD_SET(client->socketFD, &wait);
nRet = select(client->socketFD + 1, NULL, &wait, NULL, &timeout);
if (nRet == 0)
return -1;
else if (nRet < 0)
return -2;
Success:
return 0;
}
char *GetServerDate(EchoClient *client)
{
int len, ready, size = 1;
char *temp;
char *result = (char *)malloc(sizeof(char));
char *buffer = (char *)malloc(sizeof(char) * client->bufferSize);
if (!result)
return "";
else
result[0] = '\0';
if (!buffer)
return "";
else
buffer[0] = '\0';
struct timeval timeout = client->timeout;
fd_set wait;
FD_ZERO(&wait);
FD_SET(client->socketFD, &wait);
while (true)
{
if (client->block)
goto ReadMessage;
ready = select(client->socketFD + 1, &wait, NULL, NULL, &timeout);
if (ready > 0)
{
if (FD_ISSET(client->socketFD, &wait))
{
ReadMessage:
len = read(client->socketFD, buffer, client->bufferSize - 1);
if (len > 0)
{
size += len;
buffer[len] = '\0';
temp = (char *)realloc(result, sizeof(char) * size);
if (!temp)
break;
strcpy(temp, result);
result = temp;
strcat(result, buffer);
if (client->block)
continue;
}
else
break;
}
}
else
break;
}
return result;
}
int SendServerDate(EchoClient *client, char *date)
{
return write(client->socketFD, date, strlen(date));
}
void CloseConnect(EchoClient *client)
{
if (client->socketFD)
close(client->socketFD);
}
void SetClientTimeout(EchoClient *client, int s, int us)
{
client->timeout.tv_sec = s;
client->timeout.tv_usec = us;
}
void FreeClient(EchoClient *client){
free(client);
}
示例
假设服务端地址:192.168.2.2 | 端口是1001
#include <stdio.h>
int main()
{
EchoClient *client = InitClient();
SetClientTimeout(client,10,0);
char *message, ret, con;
while (true)
{
printf("尝试连接");
con = ConnectServer(client, "192.168.2.2", 1001, true);
if (con == 0)
{
ret = SendServerDate(client, "hello");
if (ret > 0)
{
message = GetServerDate(client);
printf("-->来自服务端的消息:%s", message);
}
}
CloseConnect(client);
printf("\n");
}
}