lang:c:net:client_serveur
Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
| lang:c:net:client_serveur [2022/09/30 14:04] – Mise en forme pour send/recv root | lang:c:net:client_serveur [2023/01/27 15:35] (Version actuelle) – [connect sous Windows] : ajout d'une source root | ||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| =====TCP===== | =====TCP===== | ||
| - | ====send/ | + | ====connect sous Windows==== |
| + | |||
| + | Pour ne pas avoir de connect bloquant et maitriser le timeout, on peut utiliser le code suivant : | ||
| + | |||
| + | <code c> | ||
| + | int error = -1; | ||
| + | int len = sizeof(int); | ||
| + | timeval tm; | ||
| + | fd_set set; | ||
| + | unsigned long ul = 1; | ||
| + | ioctlsocket(Socket, | ||
| + | bool ret = false; | ||
| + | if (connect(Socket, | ||
| + | sizeof(ServerAddress)) == -1) { | ||
| + | tm.tv_sec = 10; // set the timeout. 10s | ||
| + | tm.tv_usec = 0; | ||
| + | FD_ZERO(& | ||
| + | FD_SET(Socket, | ||
| + | |||
| + | if (select(Socket + 1, NULL, &set, NULL, &tm) > 0) { | ||
| + | getsockopt(Socket, | ||
| + | / | ||
| + | if (error == 0) | ||
| + | ret = true; | ||
| + | else | ||
| + | ret = false; | ||
| + | } else | ||
| + | ret = false; | ||
| + | } else | ||
| + | ret = true; | ||
| + | |||
| + | ul = 0; | ||
| + | ioctlsocket(Socket, | ||
| + | if (!ret) { | ||
| + | closesocket(Socket); | ||
| + | fprintf(stderr, | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | [[https:// | ||
| + | ====send/ | ||
| <WRAP center round important 60%> | <WRAP center round important 60%> | ||
| Ligne 186: | Ligne 226: | ||
| } | } | ||
| </ | </ | ||
| + | |||
| + | ====sendmsg/ | ||
| + | |||
| + | Transfert d'un file descripteur via socket Unix. | ||
| + | |||
| + | <WRAP center round important 60%> | ||
| + | Il faut passer par un fichier temporaire. Je n'ai pas réussi à transposer le code par des ports TCP/IP. | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===Serveur=== | ||
| + | |||
| + | <code c> | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | #define SOCK_PATH "/ | ||
| + | |||
| + | int send_msg_to_client(int socketfd, int fd) { | ||
| + | |||
| + | struct msghdr msg; | ||
| + | struct iovec iov; | ||
| + | int s; | ||
| + | char buf[CMSG_SPACE(sizeof(fd))]; | ||
| + | |||
| + | memset(& | ||
| + | memset(& | ||
| + | |||
| + | msg.msg_name = NULL; | ||
| + | msg.msg_namelen = 0; | ||
| + | iov.iov_base = ""; | ||
| + | iov.iov_len = 1; | ||
| + | msg.msg_iov = &iov; | ||
| + | msg.msg_iovlen = 1; | ||
| + | msg.msg_control = buf; | ||
| + | msg.msg_controllen = sizeof(buf); | ||
| + | msg.msg_flags = 0; | ||
| + | |||
| + | struct cmsghdr *cmsg = CMSG_FIRSTHDR(& | ||
| + | cmsg-> | ||
| + | cmsg-> | ||
| + | cmsg-> | ||
| + | |||
| + | memmove(CMSG_DATA(cmsg), | ||
| + | |||
| + | msg.msg_controllen = CMSG_SPACE(sizeof(fd)); | ||
| + | |||
| + | s = sendmsg(socketfd, | ||
| + | |||
| + | if (s < 0) { | ||
| + | perror(" | ||
| + | return 0; | ||
| + | } | ||
| + | |||
| + | return s; | ||
| + | } | ||
| + | |||
| + | int main(int argc, char *argv[]) { | ||
| + | int s, s2, len, slen; | ||
| + | socklen_t t; | ||
| + | struct sockaddr_un local, remote; | ||
| + | |||
| + | if ((s = socket(AF_UNIX, | ||
| + | perror(" | ||
| + | exit(1); | ||
| + | } | ||
| + | |||
| + | local.sun_family = AF_UNIX; | ||
| + | strcpy(local.sun_path, | ||
| + | |||
| + | unlink(local.sun_path); | ||
| + | |||
| + | len = strlen(local.sun_path) + sizeof(local.sun_family); | ||
| + | if (bind(s, (struct sockaddr *)& | ||
| + | perror(" | ||
| + | exit(1); | ||
| + | } | ||
| + | |||
| + | if (listen(s, 5) == -1) { | ||
| + | perror(" | ||
| + | exit(1); | ||
| + | } | ||
| + | |||
| + | printf(" | ||
| + | |||
| + | t = sizeof(remote); | ||
| + | if ((s2 = accept(s, (struct sockaddr *)& | ||
| + | perror(" | ||
| + | exit(1); | ||
| + | } | ||
| + | |||
| + | printf(" | ||
| + | |||
| + | int fd = open(" | ||
| + | if (fd < 0) | ||
| + | printf(" | ||
| + | |||
| + | slen = send_msg_to_client(s2, | ||
| + | |||
| + | if (slen < 0) | ||
| + | perror(" | ||
| + | |||
| + | printf(" | ||
| + | |||
| + | close(s2); | ||
| + | |||
| + | return 0; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===Client=== | ||
| + | |||
| + | <code c> | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | #define SOCK_PATH "/ | ||
| + | |||
| + | int recv_msg_from_server(int socketfd) { | ||
| + | |||
| + | struct msghdr msg = {0}; | ||
| + | |||
| + | /* On Mac OS X, the struct iovec is needed, even if it points to minimal data | ||
| + | */ | ||
| + | char m_buffer[1]; | ||
| + | struct iovec io = {.iov_base = m_buffer, .iov_len = sizeof(m_buffer)}; | ||
| + | msg.msg_iov = &io; | ||
| + | msg.msg_iovlen = 1; | ||
| + | |||
| + | char c_buffer[256]; | ||
| + | msg.msg_control = c_buffer; | ||
| + | msg.msg_controllen = sizeof(c_buffer); | ||
| + | |||
| + | if (recvmsg(socketfd, | ||
| + | printf(" | ||
| + | |||
| + | struct cmsghdr *cmsg = CMSG_FIRSTHDR(& | ||
| + | |||
| + | printf(" | ||
| + | int fd; | ||
| + | memmove(& | ||
| + | printf(" | ||
| + | |||
| + | return fd; | ||
| + | } | ||
| + | |||
| + | int main(void) { | ||
| + | int s, len, slen; | ||
| + | struct sockaddr_un remote; | ||
| + | |||
| + | if ((s = socket(AF_UNIX, | ||
| + | perror(" | ||
| + | exit(1); | ||
| + | } | ||
| + | |||
| + | printf(" | ||
| + | |||
| + | remote.sun_family = AF_UNIX; | ||
| + | strcpy(remote.sun_path, | ||
| + | len = strlen(remote.sun_path) + sizeof(remote.sun_family); | ||
| + | |||
| + | if (connect(s, (struct sockaddr *)& | ||
| + | perror(" | ||
| + | exit(1); | ||
| + | } | ||
| + | |||
| + | printf(" | ||
| + | |||
| + | slen = recv_msg_from_server(s); | ||
| + | |||
| + | char buffer[256]; | ||
| + | int nbytes; | ||
| + | if ((nbytes = read(slen, buffer, sizeof(buffer))) > 0) { | ||
| + | printf(" | ||
| + | } | ||
| + | |||
| + | close(s); | ||
| + | |||
| + | return 0; | ||
| + | } | ||
| + | </ | ||
| =====UDP===== | =====UDP===== | ||
lang/c/net/client_serveur.1664539468.txt.gz · Dernière modification : de root
