Files
stopwait_chat_ipv6/windows_chat.c
2025-12-26 15:00:35 +08:00

98 lines
2.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#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 <Ubuntu IPv6>\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);
}
}
}