#include #include #include #include #include #pragma comment(lib, "ws2_32.lib") #include "common.h" #define LOCAL_PORT 9001 #define PEER_PORT 9000 #define TIMEOUT_MS 200 int main(int argc, char *argv[]) { if (argc != 2) { printf("Usage: %s \n", argv[0]); return 1; } WSADATA wsa; WSAStartup(MAKEWORD(2,2), &wsa); SOCKET sock = socket(AF_INET6, SOCK_DGRAM, 0); struct sockaddr_in6 local = {0}; local.sin6_family = AF_INET6; local.sin6_port = htons(LOCAL_PORT); local.sin6_addr = in6addr_any; bind(sock, (struct sockaddr*)&local, sizeof(local)); struct sockaddr_in6 peer = {0}; peer.sin6_family = AF_INET6; peer.sin6_port = htons(PEER_PORT); inet_pton(AF_INET6, argv[1], &peer.sin6_addr); int timeout = TIMEOUT_MS; setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)); uint8_t send_seq = 0; uint8_t waiting_ack = 0; packet_t last_pkt; while (1) { /* 尝试接收 */ packet_t pkt; struct sockaddr_in6 from; int fromlen = sizeof(from); int n = recvfrom(sock, (char*)&pkt, sizeof(pkt), 0, (struct sockaddr*)&from, &fromlen); if (n > 0) { if (pkt.type == TYPE_DATA) { printf("\nPeer: %s", pkt.data); packet_t ack = {0}; ack.type = TYPE_ACK; ack.seq = pkt.seq; sendto(sock, (char*)&ack, sizeof(ack), 0, (struct sockaddr*)&peer, sizeof(peer)); } else if (pkt.type == TYPE_ACK && waiting_ack && pkt.seq == send_seq) { waiting_ack = 0; send_seq ^= 1; } } /* 如果不在等 ACK,允许发送 */ if (!waiting_ack) { char buf[DATA_LEN]; printf("You: "); fflush(stdout); if (fgets(buf, sizeof(buf), stdin) == NULL) continue; memset(&last_pkt, 0, sizeof(last_pkt)); last_pkt.type = TYPE_DATA; last_pkt.seq = send_seq; last_pkt.length = strlen(buf); memcpy(last_pkt.data, buf, last_pkt.length); sendto(sock, (char*)&last_pkt, sizeof(last_pkt), 0, (struct sockaddr*)&peer, sizeof(peer)); waiting_ack = 1; } else { sendto(sock, (char*)&last_pkt, sizeof(last_pkt), 0, (struct sockaddr*)&peer, sizeof(peer)); Sleep(TIMEOUT_MS); } } }