這是最簡單的tcp的架構,server只有接受(accept)一個client,然後收送資料,接著就結束。
Server
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> // inet_xx() #include <unistd.h> // close() #include <netinet/in.h> #define handle_error(msg) \ do { perror(msg); exit(EXIT_FAILURE); } while (0) int main(int argc, char *argv[]) { int sd, af, asd; // socket descriptor, address family, accepted sd struct sockaddr_in sa, peer; // socket address uint16_t port = 0; char *ip = NULL, buf[128]; socklen_t addrlen; ssize_t len; if (argc > 1) { ip = argv[1]; } af = AF_INET; if ((sd = socket(af, SOCK_STREAM, 0)) < 0) { handle_error("socket"); } memset(&sa, 0, sizeof(sa)); sa.sin_family = af; sa.sin_port = htons(port); sa.sin_addr.s_addr = INADDR_ANY; if (ip) { if (inet_pton(af, ip, &sa.sin_addr) != 1) { handle_error("inet_pton"); } } if (bind(sd, (struct sockaddr*) &sa, sizeof(sa)) < 0) { handle_error("bind"); } addrlen = sizeof(sa); if (getsockname(sd, (struct sockaddr*)&sa, &addrlen) < 0) { handle_error("getsockname"); } printf("bind on %s/%d\n", inet_ntop(sa.sin_family, &sa.sin_addr, buf, sizeof(buf)), ntohs(sa.sin_port)); if (listen(sd, 1) < -1) { // waiting to be accepted handle_error("listen"); } addrlen = sizeof(peer); if ((asd = accept(sd, (struct sockaddr*) &peer, &addrlen)) < 0) { handle_error("accept"); } if ((len = recv(asd, buf, sizeof(buf), 0)) < 0) { handle_error("recv"); } buf[len] = 0; printf("Server recv: %s\n", buf); strcpy(buf, "bye bye, peer!"); if (send(asd, buf, strlen(buf), 0) < 0) { handle_error("send"); } close(asd); close(sd); return 0; }
Client
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> // inet_xx() #include <unistd.h> // close() #include <netinet/in.h> #define handle_error(msg) \ do { perror(msg); exit(EXIT_FAILURE); } while (0) int main(int argc, char *argv[]) { int sd, af = AF_INET; // socket descriptor, address family struct sockaddr_in serv; // socket address char *serv_ip = NULL, buf[128]; socklen_t addrlen; ssize_t len; uint16_t port; if (argc <= 2) { fprintf(stderr, "Usage: %s <serv-ip> <port>\n", argv[0]); exit(EXIT_FAILURE); } serv_ip = argv[1]; port = atoi(argv[2]); if ((sd = socket(af, SOCK_STREAM, 0)) < 0) { handle_error("socket"); } memset(&serv, 0, sizeof(serv)); serv.sin_family = af; serv.sin_port = htons(port); if (inet_pton(af, serv_ip, &serv.sin_addr) != 1) { handle_error("inet_pton"); } if (connect(sd, (struct sockaddr*) &serv, sizeof(serv)) < 0) { handle_error("connect"); } strcpy(buf, "hello server!"); if (send(sd, buf, strlen(buf), 0) < 0) { handle_error("send"); } if ((len = recv(sd, buf, sizeof(buf), 0)) < 0) { handle_error("recv"); } buf[len] = 0; printf("Client recv: %s", buf); close(sd); return 0; }