From ee26b3ee749cd7906d3f1cc928c3a5603e74d6e0 Mon Sep 17 00:00:00 2001 From: kircher Date: Fri, 7 Apr 2023 17:18:58 +0800 Subject: [PATCH] add udp protocol support in example --- examples/inc/bussiness.h | 2 +- examples/inc/client.h | 4 +++- examples/inc/parameter.h | 4 ++++ examples/inc/server.h | 2 +- examples/inc/utilities.h | 2 +- examples/src/bussiness.c | 46 +++++++++++++++++++++++++++++++++------- examples/src/client.c | 11 +++++----- examples/src/parameter.c | 41 +++++++++++++++++++++++++++++------ examples/src/server.c | 26 +++++++++++++++-------- examples/src/utilities.c | 45 ++++++++++++++++++++++++++++++++------- 10 files changed, 142 insertions(+), 41 deletions(-) diff --git a/examples/inc/bussiness.h b/examples/inc/bussiness.h index f16d771..3abb448 100644 --- a/examples/inc/bussiness.h +++ b/examples/inc/bussiness.h @@ -95,7 +95,7 @@ int32_t client_bussiness(char *out, const char *in, uint32_t size, bool verify, * @param api the api * @return the result */ -int32_t server_ans(struct ServerHandler *server_handler, uint32_t pktlen, const char* api); +int32_t server_ans(struct ServerHandler *server_handler, uint32_t pktlen, const char* api, const char* domain); /** * @brief client asks server diff --git a/examples/inc/client.h b/examples/inc/client.h index ad824c7..fa506fb 100644 --- a/examples/inc/client.h +++ b/examples/inc/client.h @@ -33,6 +33,7 @@ struct ClientUnit uint64_t send_bytes; ///< total send bytes in_addr_t ip; ///< server ip uint16_t port; ///< server port + uint16_t sport; ///< client sport uint32_t connect_num; ///< total connection number uint32_t pktlen; ///< the length of peckage bool verify; ///< if we verify or not @@ -80,10 +81,11 @@ void client_info_print(struct Client *client); * @param epoll_fd the epoll file descriptor * @param ip ip address * @param port port + * @param sport sport * @param domain domain * @return the result pointer */ -int32_t client_thread_try_connect(struct ClientHandler *client_handler, int32_t epoll_fd, in_addr_t ip, uint16_t port, const char *api); +int32_t client_thread_try_connect(struct ClientHandler *client_handler, int32_t epoll_fd, in_addr_t ip, uint16_t port, uint16_t sport, const char *api); /** * @brief the single thread, client retry to connect to server, register to epoll diff --git a/examples/inc/parameter.h b/examples/inc/parameter.h index 0683822..4242d1a 100644 --- a/examples/inc/parameter.h +++ b/examples/inc/parameter.h @@ -21,6 +21,7 @@ #define PARAM_DEFAULT_AS ("server") ///< default type #define PARAM_DEFAULT_IP ("127.0.0.1") ///< default IP #define PARAM_DEFAULT_PORT (5050) ///< default port +#define PARAM_DEFAULT_SPORT (0) ///< default sport #define PARAM_DEFAULT_MODEL ("mum") ///< default model type #define PARAM_DEFAULT_CONNECT_NUM (10) ///< default connection number #define PARAM_DEFAULT_THREAD_NUM (8) ///< default thread number @@ -41,6 +42,8 @@ enum { PARAM_NUM_IP = 'i', #define PARAM_NAME_PORT ("port") ///< name of parameter port PARAM_NUM_PORT = 'p', +#define PARAM_NAME_SPORT ("sport") ///< name of parameter sport + PARAM_NUM_SPORT = 's', #define PARAM_NAME_MODEL ("model") ///< name of parameter model type PARAM_NUM_MODEL = 'm', #define PARAM_NAME_CONNECT_NUM ("connectnum") ///< name of parameter connection number @@ -91,6 +94,7 @@ struct ProgramParams { char* as; ///< as server or client char* ip; ///< IP address uint32_t port; ///< port + uint32_t sport; ///< sport char* model; ///< model type uint32_t thread_num; ///< the number of threads uint32_t connect_num; ///< the connection number diff --git a/examples/inc/server.h b/examples/inc/server.h index 45ca895..7b175db 100644 --- a/examples/inc/server.h +++ b/examples/inc/server.h @@ -142,7 +142,7 @@ int32_t sermud_listener_accept_connects(struct ServerMud *server_mud); * @param worker_unit the server worker * @return the result pointer */ -int32_t sermud_worker_proc_epevs(struct ServerMudWorker *worker_unit); +int32_t sermud_worker_proc_epevs(struct ServerMudWorker *worker_unit, const char* domain); /** * @brief the listener thread, unblock, dissymmetric server processes the events diff --git a/examples/inc/utilities.h b/examples/inc/utilities.h index a083f57..9c22abe 100644 --- a/examples/inc/utilities.h +++ b/examples/inc/utilities.h @@ -128,7 +128,7 @@ int32_t create_socket_and_listen(int32_t *socket_fd, in_addr_t ip, uint16_t port * @param domain domain * @return the result */ -int32_t create_socket_and_connect(int32_t *socket_fd, in_addr_t ip, uint16_t port, const char *domain); +int32_t create_socket_and_connect(int32_t *socket_fd, in_addr_t ip, uint16_t port, uint16_t sport, const char *domain); /** * @brief set the socket to unblock diff --git a/examples/src/bussiness.c b/examples/src/bussiness.c index b084b37..f108a9f 100644 --- a/examples/src/bussiness.c +++ b/examples/src/bussiness.c @@ -37,7 +37,7 @@ static const char bussiness_messages_cap[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // t iov[2].iov_base = buffer_in + iov_len_size + iov_len_size; iov[2].iov_len = length- iov_len_size - iov_len_size; return readv(fd, iov, iovcnt); - } else { + } else if (strcmp(api, "recvsendmsg") == 0) { struct msghdr msg_recv; struct iovec iov; @@ -52,6 +52,8 @@ static const char bussiness_messages_cap[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // t msg_recv.msg_flags = 0; return recvmsg(fd, &msg_recv, 0); + } else { + return recvfrom(fd, buffer_in, length, 0, NULL, 0); } } @@ -75,7 +77,7 @@ static const char bussiness_messages_cap[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // t iov[2].iov_len = length- iov_len_size - iov_len_size; return writev(fd, iov, iovcnt); - } else { + } else if (strcmp(api, "recvsendmsg") == 0) { struct msghdr msg_send; struct iovec iov; @@ -90,6 +92,8 @@ static const char bussiness_messages_cap[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // t msg_send.msg_flags = 0; return sendmsg(fd, &msg_send, 0); + } else { + return sendto(fd, buffer_out, length, 0, NULL, 0); } } @@ -131,7 +135,7 @@ int32_t client_bussiness(char *out, const char *in, uint32_t size, bool verify, } // server answers -int32_t server_ans(struct ServerHandler *server_handler, uint32_t pktlen, const char* api) +int32_t server_ans(struct ServerHandler *server_handler, uint32_t pktlen, const char* api, const char* domain) { const uint32_t length = pktlen; char *buffer_in = (char *)malloc(length * sizeof(char)); @@ -139,14 +143,34 @@ int32_t server_ans(struct ServerHandler *server_handler, uint32_t pktlen, const int32_t cread = 0; int32_t sread = length; + int32_t nread = 0; + struct sockaddr_in client_addr; + socklen_t len = sizeof(client_addr); + + if (strcmp(domain, "udp") == 0 && strcmp(api, "recvfromsendto") != 0) { + if (getpeername(server_handler->fd, (struct sockaddr *)&client_addr, &len) < 0) { + if (recvfrom(server_handler->fd, buffer_in, length, MSG_PEEK, (struct sockaddr *)&client_addr, &len) < 0) { + return PROGRAM_FAULT; + } + if (connect(server_handler->fd, (struct sockaddr *)&client_addr, sizeof(struct sockaddr_in)) < 0) { + return PROGRAM_FAULT; + } + } + } + while (cread < sread) { - int32_t nread = read_api(server_handler->fd, buffer_in, length, api); + if (strcmp(domain, "udp") == 0 && strcmp(api, "recvfromsendto") == 0) { + nread = recvfrom(server_handler->fd, buffer_in, length, 0, (struct sockaddr *)&client_addr, &len); + } else { + nread = read_api(server_handler->fd, buffer_in, length, api); + } + if (nread == 0) { return PROGRAM_ABORT; } else if (nread < 0) { - if (errno != EINTR && errno != EWOULDBLOCK && errno != EAGAIN) { + if (errno != EINTR && errno != EWOULDBLOCK && errno != EAGAIN) { return PROGRAM_FAULT; - } + } } else { cread += nread; continue; @@ -157,8 +181,14 @@ int32_t server_ans(struct ServerHandler *server_handler, uint32_t pktlen, const int32_t cwrite = 0; int32_t swrite = length; + int32_t nwrite = 0; while (cwrite < swrite) { - int32_t nwrite = write_api(server_handler->fd, buffer_out, length, api); + if (strcmp(domain, "udp") == 0 && strcmp(api, "recvfromsendto") == 0) { + nwrite = sendto(server_handler->fd, buffer_out, length, 0, (struct sockaddr *)&client_addr, len); + } else { + nwrite = write_api(server_handler->fd, buffer_out, length, api); + } + if (nwrite == 0) { return PROGRAM_ABORT; } else if (nwrite < 0) { @@ -256,4 +286,4 @@ int32_t client_chkans(struct ClientHandler *client_handler, uint32_t pktlen, boo free(buffer_out); return PROGRAM_OK; -} \ No newline at end of file +} diff --git a/examples/src/client.c b/examples/src/client.c index a3a3ad0..b0b99b6 100644 --- a/examples/src/client.c +++ b/examples/src/client.c @@ -85,9 +85,9 @@ void client_info_print(struct Client *client) } // the single thread, client try to connect to server, register to epoll -int32_t client_thread_try_connect(struct ClientHandler *client_handler, int32_t epoll_fd, in_addr_t ip, uint16_t port, const char *domain) +int32_t client_thread_try_connect(struct ClientHandler *client_handler, int32_t epoll_fd, in_addr_t ip, uint16_t port, uint16_t sport, const char *domain) { - int32_t create_socket_and_connect_ret = create_socket_and_connect(&(client_handler->fd), ip, port, domain); + int32_t create_socket_and_connect_ret = create_socket_and_connect(&(client_handler->fd), ip, port, sport, domain); if (create_socket_and_connect_ret == PROGRAM_INPROGRESS) { struct epoll_event ep_ev; ep_ev.events = EPOLLOUT; @@ -103,7 +103,7 @@ int32_t client_thread_try_connect(struct ClientHandler *client_handler, int32_t // the single thread, client retry to connect to server, register to epoll int32_t client_thread_retry_connect(struct ClientUnit *client_unit, struct ClientHandler *client_handler) { - int32_t clithd_try_cnntask_ret = client_thread_try_connect(client_handler, client_unit->epfd, client_unit->ip, client_unit->port, client_unit->domain); + int32_t clithd_try_cnntask_ret = client_thread_try_connect(client_handler, client_unit->epfd, client_unit->ip, client_unit->port, client_unit->sport, client_unit->domain); if (clithd_try_cnntask_ret < 0) { if (clithd_try_cnntask_ret == PROGRAM_INPROGRESS) { return PROGRAM_OK; @@ -168,7 +168,7 @@ int32_t client_thread_create_epfd_and_reg(struct ClientUnit *client_unit) } for (uint32_t i = 0; i < connect_num; ++i) { - int32_t clithd_try_cnntask_ret = client_thread_try_connect(client_unit->handlers + i, client_unit->epfd, client_unit->ip, client_unit->port, client_unit->domain); + int32_t clithd_try_cnntask_ret = client_thread_try_connect(client_unit->handlers + i, client_unit->epfd, client_unit->ip, client_unit->port, client_unit->sport, client_unit->domain); if (clithd_try_cnntask_ret < 0) { if (clithd_try_cnntask_ret == PROGRAM_INPROGRESS) { continue; @@ -230,7 +230,7 @@ int32_t clithd_proc_epevs(struct ClientUnit *client_unit) for (int32_t i = 0; i < epoll_nfds; ++i) { struct epoll_event *curr_epev = client_unit->epevs + i; - if (curr_epev->events == EPOLLERR) { + if (curr_epev->events == EPOLLERR && errno != 0) { PRINT_ERROR("client epoll wait error! %d", curr_epev->events); return PROGRAM_FAULT; } else if (curr_epev->events == EPOLLOUT) { @@ -364,6 +364,7 @@ int32_t client_create_and_run(struct ProgramParams *params) client_unit->send_bytes = 0; client_unit->ip = inet_addr(params->ip); client_unit->port = htons(params->port); + client_unit->sport = htons(params->sport); client_unit->connect_num = params->connect_num; client_unit->pktlen = params->pktlen; client_unit->verify = params->verify; diff --git a/examples/src/parameter.c b/examples/src/parameter.c index 3116a18..a152700 100644 --- a/examples/src/parameter.c +++ b/examples/src/parameter.c @@ -19,6 +19,7 @@ const char prog_short_opts[] = \ "a:" // as "i:" // ip "p:" // port + "s:" // sport "m:" // model "t:" // thread number "c:" // connect number @@ -39,6 +40,7 @@ const struct ProgramOption prog_long_opts[] = \ {PARAM_NAME_AS, REQUIRED_ARGUMETN, NULL, PARAM_NUM_AS}, {PARAM_NAME_IP, REQUIRED_ARGUMETN, NULL, PARAM_NUM_IP}, {PARAM_NAME_PORT, REQUIRED_ARGUMETN, NULL, PARAM_NUM_PORT}, + {PARAM_NAME_SPORT, REQUIRED_ARGUMETN, NULL, PARAM_NUM_SPORT}, {PARAM_NAME_MODEL, REQUIRED_ARGUMETN, NULL, PARAM_NUM_MODEL}, {PARAM_NAME_THREAD_NUM, REQUIRED_ARGUMETN, NULL, PARAM_NUM_THREAD_NUM}, {PARAM_NAME_CONNECT_NUM, REQUIRED_ARGUMETN, NULL, PARAM_NUM_CONNECT_NUM}, @@ -93,6 +95,19 @@ void program_param_parse_port(struct ProgramParams *params) } } +// set `sport` parameter +void program_param_parse_sport(struct ProgramParams *params) +{ + int32_t sport_arg = strtol(optarg, NULL, 0); + printf("%d\n", sport_arg); + if (CHECK_VAL_RANGE(sport_arg, UNIX_TCP_PORT_MIN, UNIX_TCP_PORT_MAX) == true) { + params->sport = (uint32_t)sport_arg; + } else { + PRINT_ERROR("illigal argument -- %s \n", optarg); + exit(PROGRAM_ABORT); + } +} + // set `model` parameter void program_param_parse_model(struct ProgramParams *params) { @@ -131,7 +146,7 @@ void program_param_parse_threadnum(struct ProgramParams *params) // set `domain` parameter void program_param_parse_domain(struct ProgramParams *params) { - if (strcmp(optarg, "unix") == 0 || strcmp(optarg, "posix") == 0) { + if (strcmp(optarg, "unix") == 0 || strcmp(optarg, "tcp") == 0 || strcmp(optarg, "udp") == 0) { params->domain = optarg; } else { PRINT_ERROR("illigal argument -- %s \n", optarg); @@ -143,7 +158,7 @@ void program_param_parse_domain(struct ProgramParams *params) void program_param_parse_api(struct ProgramParams *params) { printf("aaaaaa %s\n", optarg); - if (strcmp(optarg, "readwrite") == 0 || strcmp(optarg, "readvwritev") == 0 || strcmp(optarg, "recvsend") == 0 || strcmp(optarg, "recvsendmsg") == 0) { + if (strcmp(optarg, "readwrite") == 0 || strcmp(optarg, "readvwritev") == 0 || strcmp(optarg, "recvsend") == 0 || strcmp(optarg, "recvsendmsg") == 0 || strcmp(optarg, "recvfromsendto") == 0) { params->api = optarg; } else { PRINT_ERROR("illigal argument -- %s \n", optarg); @@ -191,6 +206,7 @@ void program_params_init(struct ProgramParams *params) params->as = PARAM_DEFAULT_AS; params->ip = PARAM_DEFAULT_IP; params->port = PARAM_DEFAULT_PORT; + params->sport = PARAM_DEFAULT_SPORT; params->model = PARAM_DEFAULT_MODEL; params->thread_num = PARAM_DEFAULT_THREAD_NUM; params->connect_num = PARAM_DEFAULT_CONNECT_NUM; @@ -213,18 +229,21 @@ void program_params_help(void) printf(" client: as client. \n"); printf("-i, --ip [???.???.???.???]: set ip address. \n"); printf("-p, --port [????]: set port number in range of %d - %d. \n", UNIX_TCP_PORT_MIN, UNIX_TCP_PORT_MAX); + printf("-s, --sport [????]: set sport number in range of %d - %d. \n", UNIX_TCP_PORT_MIN, UNIX_TCP_PORT_MAX); printf("-m, --model [mum | mud]: set the network model. \n"); printf(" mum: multi thread, unblock, multiplexing IO network model. \n"); printf(" mud: multi thread, unblock, dissymmetric network model. \n"); printf("-t, --threadnum [???]: set thread number in range of %d - %d. \n", THREAD_NUM_MIN, THREAD_NUM_MAX); printf("-c, --connectnum [???]: set connection number of each thread. \n"); - printf("-D, --domain [unix | posix]: set domain type is server or client. \n"); + printf("-D, --domain [unix | tcp | udp]: set domain type is server or client. \n"); printf(" unix: use unix's api. \n"); - printf(" posix: use posix api. \n"); - printf("-A, --api [readwrite | recvsend | recvsendmsg]: set api type is server or client. \n"); + printf(" tcp: use tcp api. \n"); + printf(" udp: use udp api. \n"); + printf("-A, --api [readwrite | recvsend | recvsendmsg | recvfromsendto]: set api type is server or client. \n"); printf(" readwrite: use `read` and `write`. \n"); printf(" recvsend: use `recv and `send`. \n"); printf(" recvsendmsg: use `recvmsg` and `sendmsg`. \n"); + printf(" recvfromsendto: use `recvfrom` and `sendto`. \n"); printf("-P, --pktlen [????]: set packet length in range of %d - %d. \n", MESSAGE_PKTLEN_MIN, MESSAGE_PKTLEN_MAX); printf("-v, --verify: set to verifying the message packet. \n"); printf("-r, --ringpmd: set to use ringpmd. \n"); @@ -259,6 +278,9 @@ int32_t program_params_parse(struct ProgramParams *params, uint32_t argc, char * case (PARAM_NUM_PORT): program_param_parse_port(params); break; + case (PARAM_NUM_SPORT): + program_param_parse_sport(params); + break; case (PARAM_NUM_MODEL): program_param_parse_model(params); break; @@ -303,7 +325,7 @@ int32_t program_params_parse(struct ProgramParams *params, uint32_t argc, char * } } - if (strcmp(params->domain, "unix") == 0) { + if (strcmp(params->domain, "tcp") != 0) { params->thread_num = 1; params->connect_num = 1; } @@ -319,6 +341,9 @@ void program_params_print(struct ProgramParams *params) printf("--> [as]: %s \n", params->as); printf("--> [server ip]: %s \n", params->ip); printf("--> [server port]: %u \n", params->port); + if (params->sport && strcmp(params->as, "client") == 0) { + printf("--> [client sport]: %u \n", params->sport); + } if (strcmp(params->as, "server") == 0) { printf("--> [model]: %s \n", params->model); } @@ -333,8 +358,10 @@ void program_params_print(struct ProgramParams *params) printf("--> [api]: read & write \n"); } else if (strcmp(params->api, "recvsend") == 0) { printf("--> [api]: recv & send \n"); - } else { + } else if (strcmp(params->api, "recvsendmsg") == 0) { printf("--> [api]: recvmsg & sendmsg \n"); + } else { + printf("--> [api]: recvfrom & sendto \n"); } printf("--> [packet length]: %u \n", params->pktlen); printf("--> [verify]: %s \n", (params->verify == true) ? "on" : "off"); diff --git a/examples/src/server.c b/examples/src/server.c index 7ee73db..6a35f33 100644 --- a/examples/src/server.c +++ b/examples/src/server.c @@ -13,7 +13,6 @@ #include "server.h" - static pthread_mutex_t server_debug_mutex; // the server mutex for debug // server debug information print @@ -142,6 +141,10 @@ int32_t sermud_listener_accept_connects(struct ServerMud *server_mud) struct sockaddr_in accept_addr; uint32_t sockaddr_in_len = sizeof(struct sockaddr_in); int32_t accept_fd; + if (strcmp(server_mud->domain, "udp") == 0) { + break; + } + if (strcmp(server_mud->accept, "ac4") == 0) { accept_fd = accept4(server_mud->listener.fd, (struct sockaddr *)&accept_addr, &sockaddr_in_len, SOCK_CLOEXEC); } else { @@ -175,7 +178,7 @@ int32_t sermud_listener_accept_connects(struct ServerMud *server_mud) server_mud->workers = worker; - if (pthread_create(tid, NULL, sermud_worker_create_and_run, server_mud->workers) < 0) { + if (pthread_create(tid, NULL, sermud_worker_create_and_run, server_mud) < 0) { PRINT_ERROR("server can't create poisx thread %d! ", errno); return PROGRAM_FAULT; } @@ -187,7 +190,7 @@ int32_t sermud_listener_accept_connects(struct ServerMud *server_mud) } // the worker thread, unblock, dissymmetric server processes the events -int32_t sermud_worker_proc_epevs(struct ServerMudWorker *worker_unit) +int32_t sermud_worker_proc_epevs(struct ServerMudWorker *worker_unit, const char* domain) { int32_t epoll_nfds = epoll_wait(worker_unit->epfd, worker_unit->epevs, SERVER_EPOLL_SIZE_MAX, SERVER_EPOLL_WAIT_TIMEOUT); if (epoll_nfds < 0) { @@ -206,7 +209,7 @@ int32_t sermud_worker_proc_epevs(struct ServerMudWorker *worker_unit) if (curr_epev->events == EPOLLIN) { struct ServerHandler *server_handler = (struct ServerHandler *)curr_epev->data.ptr; - int32_t server_ans_ret = server_ans(server_handler, worker_unit->pktlen, worker_unit->api); + int32_t server_ans_ret = server_ans(server_handler, worker_unit->pktlen, worker_unit->api, domain); if (server_ans_ret == PROGRAM_FAULT) { struct epoll_event ep_ev; if (epoll_ctl(worker_unit->epfd, EPOLL_CTL_DEL, server_handler->fd, &ep_ev) < 0) { @@ -263,13 +266,14 @@ void *sermud_worker_create_and_run(void *arg) { pthread_detach(pthread_self()); - struct ServerMudWorker *worker_unit = (struct ServerMudWorker *)arg; + struct ServerMudWorker *worker_unit = ((struct ServerMud *)arg)->workers; + char* domain = ((struct ServerMud *)arg)->domain; if (sermud_worker_create_epfd_and_reg(worker_unit) < 0) { exit(PROGRAM_FAULT); } while (true) { - if (sermud_worker_proc_epevs(worker_unit) < 0) { + if (sermud_worker_proc_epevs(worker_unit, domain) < 0) { exit(PROGRAM_FAULT); } } @@ -428,6 +432,10 @@ int32_t sersum_accept_connects(struct ServerMumUnit *server_unit, struct ServerH struct sockaddr_in accept_addr; uint32_t sockaddr_in_len = sizeof(struct sockaddr_in); int32_t accept_fd; + if (strcmp(server_unit->domain, "udp") == 0) { + break; + } + if (strcmp(server_unit->accept, "ac4") == 0) { accept_fd = accept4(server_unit->listener.fd, (struct sockaddr *)&accept_addr, &sockaddr_in_len, SOCK_CLOEXEC); } else { @@ -479,7 +487,7 @@ int32_t sersum_proc_epevs(struct ServerMumUnit *server_unit) } if (curr_epev->events == EPOLLIN) { - if (curr_epev->data.ptr == (void *)&(server_unit->listener)) { + if (curr_epev->data.ptr == (void *)&(server_unit->listener) && strcmp(server_unit->domain, "udp") != 0) { int32_t sersum_accept_connects_ret = sersum_accept_connects(server_unit, &(server_unit->listener)); if (sersum_accept_connects_ret < 0) { PRINT_ERROR("server try accept error %d! ", sersum_accept_connects_ret); @@ -490,12 +498,12 @@ int32_t sersum_proc_epevs(struct ServerMumUnit *server_unit) struct ServerHandler *server_handler = (struct ServerHandler *)curr_epev->data.ptr; struct sockaddr_in connect_addr; socklen_t connect_addr_len = sizeof(connect_addr); - if (getpeername(server_handler->fd, (struct sockaddr *)&connect_addr, &connect_addr_len) < 0) { + if (strcmp(server_unit->domain, "udp") != 0 && getpeername(server_handler->fd, (struct sockaddr *)&connect_addr, &connect_addr_len) < 0) { PRINT_ERROR("server can't socket peername %d! ", errno); return PROGRAM_FAULT; } - int32_t server_ans_ret = server_ans(server_handler, server_unit->pktlen, server_unit->api); + int32_t server_ans_ret = server_ans(server_handler, server_unit->pktlen, server_unit->api, server_unit->domain); if (server_ans_ret == PROGRAM_FAULT) { --server_unit->curr_connect; struct epoll_event ep_ev; diff --git a/examples/src/utilities.c b/examples/src/utilities.c index 877e611..0a65784 100644 --- a/examples/src/utilities.c +++ b/examples/src/utilities.c @@ -17,18 +17,24 @@ // create the socket and listen int32_t create_socket_and_listen(int32_t *socket_fd, in_addr_t ip, uint16_t port, const char *domain) { - if (strcmp(domain, "posix") == 0) { + if (strcmp(domain, "tcp") == 0) { *socket_fd = socket(AF_INET, SOCK_STREAM, 0); if (*socket_fd < 0) { PRINT_ERROR("can't create socket %d! ", errno); return PROGRAM_FAULT; } - } else { + } else if (strcmp(domain, "unix") == 0) { *socket_fd = socket(AF_UNIX, SOCK_STREAM, 0); if (*socket_fd < 0) { PRINT_ERROR("can't create socket %d! ", errno); return PROGRAM_FAULT; } + } else if (strcmp(domain, "udp") == 0) { + *socket_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (*socket_fd < 0) { + PRINT_ERROR("can't create socket %d! ", errno); + return PROGRAM_FAULT; + } } int32_t port_multi = 1; @@ -42,7 +48,7 @@ int32_t create_socket_and_listen(int32_t *socket_fd, in_addr_t ip, uint16_t port return PROGRAM_FAULT; } - if (strcmp(domain, "posix") == 0) { + if (strcmp(domain, "tcp") == 0) { struct sockaddr_in socket_addr; memset_s(&socket_addr, sizeof(socket_addr), 0, sizeof(socket_addr)); socket_addr.sin_family = AF_INET; @@ -57,7 +63,7 @@ int32_t create_socket_and_listen(int32_t *socket_fd, in_addr_t ip, uint16_t port PRINT_ERROR("server socket can't lisiten %d! ", errno); return PROGRAM_FAULT; } - } else { + } else if (strcmp(domain, "unix") == 0) { struct sockaddr_un socket_addr; unlink(SOCKET_UNIX_DOMAIN_FILE); socket_addr.sun_family = AF_UNIX; @@ -71,16 +77,30 @@ int32_t create_socket_and_listen(int32_t *socket_fd, in_addr_t ip, uint16_t port PRINT_ERROR("server socket can't lisiten %d! ", errno); return PROGRAM_FAULT; } + } else if (strcmp(domain, "udp") == 0) { + struct sockaddr_in socket_addr; + memset_s(&socket_addr, sizeof(socket_addr), 0, sizeof(socket_addr)); + socket_addr.sin_family = AF_INET; + socket_addr.sin_addr.s_addr = ip; + socket_addr.sin_port = port; + if (bind(*socket_fd, (struct sockaddr *)&socket_addr, sizeof(struct sockaddr_in)) < 0) { + PRINT_ERROR("can't bind the address to socket %d! ", errno); + return PROGRAM_FAULT; + } } return PROGRAM_OK; } // create the socket and connect -int32_t create_socket_and_connect(int32_t *socket_fd, in_addr_t ip, uint16_t port, const char *domain) +int32_t create_socket_and_connect(int32_t *socket_fd, in_addr_t ip, uint16_t port, uint16_t sport, const char *domain) { - if (strcmp(domain, "posix") == 0) { - *socket_fd = socket(AF_INET, SOCK_STREAM, 0); + if (strcmp(domain, "tcp") == 0 || strcmp(domain, "udp") == 0) { + if (strcmp(domain, "tcp") == 0) { + *socket_fd = socket(AF_INET, SOCK_STREAM, 0); + } else { + *socket_fd = socket(AF_INET, SOCK_DGRAM, 0); + } if (*socket_fd < 0) { PRINT_ERROR("client can't create socket %d! ", errno); return PROGRAM_FAULT; @@ -94,6 +114,14 @@ int32_t create_socket_and_connect(int32_t *socket_fd, in_addr_t ip, uint16_t por struct sockaddr_in server_addr; memset_s(&server_addr, sizeof(server_addr), 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; + if (sport) { + server_addr.sin_addr.s_addr = htonl(INADDR_ANY); + server_addr.sin_port = sport; + if (bind(*socket_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in)) < 0) { + PRINT_ERROR("can't bind the address to socket %d! ", errno); + return PROGRAM_FAULT; + } + } server_addr.sin_addr.s_addr = ip; server_addr.sin_port = port; if (connect(*socket_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in)) < 0) { @@ -104,7 +132,7 @@ int32_t create_socket_and_connect(int32_t *socket_fd, in_addr_t ip, uint16_t por return PROGRAM_FAULT; } } - } else { + } else if (strcmp(domain, "unix") == 0) { *socket_fd = socket(AF_UNIX, SOCK_STREAM, 0); if (*socket_fd < 0) { PRINT_ERROR("client can't create socket %d! ", errno); @@ -123,6 +151,7 @@ int32_t create_socket_and_connect(int32_t *socket_fd, in_addr_t ip, uint16_t por } } } + return PROGRAM_OK; } -- 2.23.0