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 [2019/01/17 14:12] – ↷ Liens modifiés en raison d'un déplacement. 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===== | ||
- | <note important> | + | ====connect sous Windows==== |
- | {{: | + | |
- | [[http:// | + | Pour ne pas avoir de connect bloquant et maitriser le timeout, on peut utiliser le code suivant |
- | [[https:// | + | <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%> | ||
+ | TODO. recv en non bloquant. | ||
+ | </ | ||
+ | |||
+ | {{: | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | [[https:// | ||
[[http:// | [[http:// | ||
- | [[https:// | + | [[https:// |
- | ====Serveur==== | + | |
+ | ===Serveur=== | ||
<file c serveur.c> | <file c serveur.c> | ||
#define _GNU_SOURCE | #define _GNU_SOURCE | ||
Ligne 118: | Ligne 168: | ||
</ | </ | ||
- | ====Client==== | + | ===Client=== |
<file c client.c> | <file c client.c> | ||
#include < | #include < | ||
Ligne 176: | 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===== | ||
- | <note important> | + | <WRAP center round important |
+ | TODO | ||
+ | </WRAP> | ||
lang/c/net/client_serveur.1547730731.txt.gz · Dernière modification : 2019/01/17 14:12 de root