gpt4 book ai didi

linux - BSD套接字不工作

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:01:16 25 4
gpt4 key购买 nike

更新:根据建议更新了 src。 strcat a\n\0 到命令并更改 sizeof。客户端在发送时“成功”,但服务器在接收时从未“成功”。

我已经付出了很多努力来尝试让一个常规的旧 TCP 套接字工作。我基本上有一个简单的客户端和服务器设置。目前我在我的服务器上没有收到任何东西,我在我的客户端上只收到 4 个字节(本例中为“GOTY”)。

服务器输出输出这个并继续:

RECEIVED (null)

客户端输出只会阻塞并且永远不会停止。如果我终止服务器,我会得到这个输出

Connect success
Received Response:

服务器

int Server::update(char *getbuf)
{
int ready = poll(pollfds, 1, 100);

if (ready == -1)
{
logger.info("Poll failed");
return FALSE;
}

if (pollfds[0].revents & POLLIN)
{
ssize_t z;

logger.info("Connection available");

struct sockaddr_in client_address;
memset(&client_address, 0, sizeof client_address);
socklen_t alen = sizeof(client_address);

// ACCEPT
clientsocket = accept(serversocket, (struct sockaddr *)&client_address, &alen);
if(!clientsocket)
logger.fail("Accept Fail");

// READ
z = recv(clientsocket, getbuf, 512, MSG_WAITALL);
if (z < 0)
fprintf(stderr,"receive failure\n");
else
fprintf(stderr,"receive succeed\n");

getbuf[z] = 0;

respond(getbuf);

//closeConnection();

logger.data("RECEIVED %s", getbuf);

getbuf[z] = 0;

return TRUE;
}

return FALSE;
}

void Server::respond(char *response)
{
// SEND
ssize_t z;

z = send(clientsocket, response, strlen(response), 0);
if (z < 0)
fprintf(stderr,"send failure\n");
else
fprintf(stderr,"send succeed\n");
}

客户

我添加了客户端代码。我现在使用 strlen,但它似乎无济于事。

int main(int argc, char **argv)
{
int abort = 0;
int port;
in_addr_t address;
char *command;

ssize_t z;
int com_socket;
struct sockaddr_in server_address;
struct timeval timeout;

int opt;
int val = 0;
char getbuf[512];

//Defaults
address = inet_addr("127.0.0.1");
port = 4949;

//INCLUDED ARGUMENTS FROM CLI
while((opt = getopt(argc, argv, "a:p:c:")) > 0)
{
switch(opt)
{
case 'a':
address = inet_addr(optarg);
break;
case 'p':
port = atoi(optarg);
break;
case 'c':
abort = 1;
command = (char *)optarg;
break;
default:
fprintf(stderr, "-a IPADDRESS -p PORT -c COMMAND\n",argv[0]);
}
}

// Server
memset(&server_address, 0, sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_port = htons(port);
server_address.sin_addr.s_addr = address;

if (server_address.sin_addr.s_addr == INADDR_NONE)
fprintf(stderr, "Server address failed\n");

if(!abort)
{
fprintf(stderr, "No Command given\n");
fprintf(stderr, "-a IPADDRESS -p PORT -C COMMAND\n");
exit(0);
}
else
{
fprintf(stderr, "Address %s Port %d Command %s\n", inet_ntoa(server_address.sin_addr), port, command);
}

// Create com_socket
com_socket = socket(PF_INET, SOCK_STREAM, 0);
if (com_socket == -1)
fprintf(stderr, "Socket failed\n");

/*
// Client
struct sockaddr_in client_address;
memset(&client_address,0,sizeof client_address);
client_address.sin_family = AF_INET;
client_address.sin_port = 0;
client_address.sin_addr.s_addr = ntohl(INADDR_ANY);

if (client_address.sin_addr.s_addr == INADDR_NONE)
fprintf(stderr, "Client address failed\n");

// Bind
z= bind(com_socket, (struct sockaddr *)&client_address, sizeof (client_address));
if ( z == -1 )
fprintf(stderr,"Binding port\n");
*/

timeout.tv_sec = 2; /* 2 seconds */
timeout.tv_usec = 0; /* + 0 usec */

socklen_t addrlen = sizeof(struct sockaddr_in);

// Connect
//z = connectWithTimeout(com_socket, (struct sockaddr *) &server_address, len_inet, &timeout);
z = connect(com_socket, (struct sockaddr *) &server_address, sizeof(server_address));
if(z == -1)
{
if(errno == EINPROGRESS)
{
fprintf(stderr, "EINPROGRESS non block start\n");
}

if(errno == EALREADY)
{
fprintf(stderr, "EALREADY non block subsequent request\n");
}

fprintf(stderr, "Connect failed\n");
}
else
fprintf(stderr, "Connect success\n");

strcat(command, "\n\0");

// SEND
z = send(com_socket, command, strlen(command)+2, 0);
if (z < 0)
fprintf(stderr,"send failure\n");
else
fprintf(stderr,"send succeed\n");

// READ
z = recv(com_socket, getbuf, 512, MSG_WAITALL);
if (z < 0)
fprintf(stderr,"receive failure\n");
else
fprintf(stderr,"receive succeed\n");

// Output
fprintf(stderr, "Received Response: %s\n", getbuf);

close(com_socket);

exit(1);
}

我只是不知道为什么这不起作用。我一遍又一遍地检查它。

这是一个嵌入式Linux系统。

最佳答案

在服务器中:这完全是错误的。 strlen() 返回在 read()/recv() 之前缓冲区中的字符串的长度。

    // READ
z = recv(clientsocket, getbuf, strlen(getbuf), MSG_WAITALL);
if (z < 0)
fprintf(stderr,"receive failure\n");

此外:在 respond() 中,strlen() 假定响应“string”是空终止的。它不是。

z = send(clientsocket, response, strlen(response), 0);

并且客户端代码中似乎存在相同类型的错误。

更新:由于 OP 不知道如何在没有字符串函数的情况下生存,我将说明如何做到这一点。

 ... snipped ...
// READ
z = recv(clientsocket, getbuf, 512, MSG_WAITALL);
if (z < 0) {
// .... if (errno == EAGAIN) continue;
fprintf(stderr,"receive failure %d(%s) \n"
, errno, strerror(errno) );
break; }

fprintf(stderr,"receive succeed\n");

respond(getbuf, z);

return TRUE;
}
return FALSE;
}

void respond(char *response, size_t siz)
{
// SEND
size_t done;
ssize_t z;

for (done = 0; done < siz; done += z) {
z = send(clientsocket, response+done, siz-done, 0);
if (z < 0) {
if (errno == EAGAIN) continue;
fprintf(stderr,"send failure %d(%s)\n"
, errno, strerror(errno) );
break; }
fprintf(stderr,"send succeed\n");
}
}

关于linux - BSD套接字不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9043343/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com