介绍
C Liunx实现EchoServer非阻塞客户端(TPC协议)
支持库
#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"); } }
文章有(1)条网友点评
这个代码有问题,在读取的时候容易出错,就当作参考吧