我正在开发一个简单的项目,因为我想了解有关Linux下套接字编程的更多信息。我创建了一个非常简单的服务器,它将接受连接并使用单个语句进行响应。但是,我添加了一个while循环以保持连接处于活动状态,因此我可以继续发送命令而不会断开连接。但是,一旦我发送第一个命令,服务器将响应连接。在第一次响应之后,它只是处于空闲状态并退出响应。从代码中可以看出,我在while循环内部和外部尝试了accept系统调用,因为我不确定在同一个客户端上多次调用accept会导致它挂起。一旦我在while循环之外移动了接受调用,该函数仍然挂起,所以我不确定从这里开始。
#include "server.h"
#include <netinet/in.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct server {
int sockfd;
int client_socket; //the socket used for communication with the client
int backlog; //maximum pending connections
struct sockaddr_in *serv_addr;
struct sockaddr_in *client_addr; //the clients information when it connects
};
int server_init(server **serv, int max_connections)
{
*serv = (server *)malloc(sizeof(server));
if (*serv) {
(*serv)->backlog = max_connections;
(*serv)->sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
(*serv)->serv_addr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
if ((*serv)->serv_addr)
memset((*serv)->serv_addr->sin_zero, 0, sizeof((*serv)->serv_addr->sin_zero));
else {
free(*serv);
return -1;
}
(*serv)->serv_addr->sin_family = AF_INET;
(*serv)->serv_addr->sin_addr.s_addr = INADDR_ANY;
} else {
return -1;
}
return 0;
}
/*
* Bind the server to a port and start listening
*/
int server_bind(server *serv, int port)
{
int result = 0;
serv->serv_addr->sin_port = htons(port);
if (bind(serv->sockfd, (struct sockaddr *)serv->serv_addr, (socklen_t)sizeof(*(serv->serv_addr))) < 0)
return -1; //if the bind call fails, I dont want to continue to try the listen call
if (listen(serv->sockfd, serv->backlog) < 0)
result = -1;
return result;
}
int server_unbind(server *serv)
{
int result = 0;
if (close(serv->client_socket) < 0)
result = -1;
if (close(serv->sockfd) < 0)
result = -1;
return result;
}
int server_accept_connections(server *serv, int (*process_data)(char *buffer, ssize_t length, int client_scoket))
{
int result = 0;
char *buffer = (char *) malloc(sizeof(char) * 250);
if (buffer) {
int length = sizeof((serv)->client_addr); //may do something with this to keep from calculating it every time
serv->client_socket = accept(serv->sockfd, (struct sockaddr *)(serv)->client_addr, &length);
while (result == 0) {
//int length = sizeof((serv)->client_addr);
//serv->client_socket = accept(serv->sockfd, (struct sockaddr *)(serv)->client_addr, &length);
ssize_t data_length = recv(serv->client_socket, buffer, sizeof(buffer), 0);
result = (* process_data)(buffer, data_length, serv->client_socket);
}
result = 0;
}
else
result = -1;
free(buffer);
return result;
}
void server_destroy(server *serv)
{
if (serv) {
free(serv->serv_addr);
free(serv);
}
}
#include <stdio.h>
#include "server.h"
#include <string.h>
#include <stdlib.h>
int process_netdata(char *buffer, ssize_t length, int socket_desc)
{
printf("%s",buffer);
if(strcmp(buffer, "quit") != 0) {
char *str = "I got your message";
int str_length = strlen(str);
write(socket_desc, str, str_length);
return 0;
}
else {
char *str = "quit received";
int str_length = strlen(str);
write(socket_desc, str, str_length);
return -1;
}
}
int main(int argc, char **argv)
{
server *server;
int value = 0;
value = server_init(&server, 10);
printf("server_init: %i\n", value);
value = server_bind(server, 2021);
printf("server_bind: %i\n", value);
value = server_accept_connections(server, &process_netdata);
printf("server_accept: %i\n", value);
value = server_unbind(server);
printf("server_unbind: %i\n", value);
value = server_destroy(server);
printf("server_destroy: %i\n", value);
return 0;
}
答案 0 :(得分:2)
您缺少fork,以便父级继续侦听(接受)新连接,而子级则在已建立的连接上运行。