gpt4 book ai didi

c - 关于C语言socket编程的几个问题

转载 作者:行者123 更新时间:2023-11-30 21:18:02 29 4
gpt4 key购买 nike

我有一些关于在 C 中通过 Telnet/TCP 进行套接字编程的问题:

  1. 当我激活客户端远程访问程序时,它的行为正常,但是如果我在程序运行时关闭终端,则发出的最后一个远程命令决定重复自身,直到程序终止,该怎么办顶这个?

  2. 当我的程序到达套接字代码(即下面我声明的函数)时,即使我没有打开客户端,我也无法再手动/本地操作我的程序。我已经用谷歌解决了这个问题,最重要的结果似乎与接受套接字命令阻止访问有关。注意:我尝试过使用非阻塞套接字,但仍然没有成功。另请注意,我希望我的程序能够同时手动/本地操作,即使远程终端已激活,并且如果可能的话,当远程终端启动时手动控制程序以反射(reflect)远程终端上的更改.

  3. 最后,我希望能够键入单词或短语来激活命令,而不仅仅是单个字符。如果我输入一个单词而不是一个字符,我会收到多字符错误,如果我尝试使用双引号,尽管成功编译,它似乎不会响应任何内容。据我所知,如果您使用 C++ 而不是 C 进行编程,则可以使用双引号,但是我听说可以使用单词在 C 中发出命令。

我在下面发布了我的套接字代码,我知道 while(1) 循环是一个问题,但这是当前阻止它关闭连接的唯一原因。另请注意,remotecommand 函数是在我的主程序中以无限循环的形式声明的,但在运行时,尽管关闭了连接,但在运行声明的函数后没有任何代码。

void sigchld_handler(int s)
{
while(waitpid(-1, NULL, WNOHANG) > 0);
}

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET) {
return &(((struct sockaddr_in*)sa)->sin_addr);
}

return &(((struct sockaddr_in6*)sa)->sin6_addr);
}



int sockfd, new_fd; // listen on sock_fd, new connection on new_fd
int rc;
struct addrinfo hints, *servinfo, *p;
struct sockaddr_storage their_addr; // connector's address information
socklen_t sin_size;
struct sigaction sa;
int yes=1;
char s[INET6_ADDRSTRLEN];
int rv;
char recv_client_msg[100];


memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; // use my IP

if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}

// loop throui_pgh all the results and bind to the first we can
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype,
p->arotocol)) == -1) {
perror("server: socket");
continue;
}

if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}

if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("server: bind");
continue;
}

break;
}

if (p == NULL) {
fprintf(stderr, "server: failed to bind\n");
return 2;
}

freeaddrinfo(servinfo); // all done with this structure

if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}

sa.sa_handler = sigchld_handler; // reap all dead processes
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction");
exit(1);
}

int RemoteCommand(){ // main accept() loop
sin_size = sizeof their_addr;
new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
if (new_fd == -1) {
perror("accept");
return(-1);
}
//fcntl(sockfd, F_SETFL, O_NONBLOCK);
//fcntl(new_fd, F_SETFL, O_NONBLOCK);

inet_ntop(their_addr.ss_family,
get_in_addr((struct sockaddr *)&their_addr),
s, sizeof s);
printf("server: got connection from %s\n", s);

if (!fork()) { // this is the child process
close(sockfd); // child doesn't need the listener
if (send(new_fd, "Hello, world!", 13, 0) == -1)
perror("send");

while(1)
{
rc = read(new_fd, recv_client_msg, sizeof(recv_client_msg));
if(write(new_fd,recv_client_msg, rc) <0 ) { printf("error writing to stream socket\n"); }
if(recv_client_msg[0]=='1') {commandSwitch(1,1);}
if(recv_client_msg[0]=='2') {commandSwitch(1,2);}
if(recv_client_msg[0]=='3') {commandSwitch(2,1);}
if(recv_client_msg[0]=='4') {commandSwitch(2,2);}
}
close(new_fd);
exit(0);
}
close(new_fd); // parent doesn't need this
return(0);
}
//end of socket setup

这是我第一次使用套接字,因此如果有人有解决方案,请尝试详细解释您的意思。

最佳答案

您需要实际检查 read 返回的内容。出错时返回 -1,连接正常关闭时返回 0

由于您不检查这一点,因此您不会注意到连接已关闭或有任何错误,而只是尝试接收、接收、接收,没有任何反应,并且一遍又一遍地使用相同的数据。

<小时/>

正确处理的示例:

rc = read(...);

// At this point, we don't know if we have actually received anything

if (rc <= 0)
{
if (rc == 0)
printf("Connection closed in a nice way by the other end\n");
else
fprintf(stderr, "Error reading: %s\n", strerror(errno));

// Do note that not *all* errors are actually fatal,
// For example: If you have non-blocking sockets then you
// could have `errno == EWOULDBLOCK` and that's okay, and
// means you should try to receive again in a little while

break; // Break out of loop, let the connection be closed
}

// Now we *know* we have received something, process the data received
// To be more precise, we have received `rc` byes of data

关于c - 关于C语言socket编程的几个问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30845764/

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