send, recv 함수 마지막 인자에 옵션을 전달할 수 있다
MSG_OOB : 긴급 메시지 전송
MSG_PEEK : 입력 버퍼에 수신된 데이터 존재하는지 확인
MSG_DONTWAIT 옵션과 묶여, 블로킹 안 하고 데이터 존재유무만 판단하는 함수에 사용됨데이터를 모아서 전송, 모아서 수신
윈도우에선 리눅스에서 썼던 방식의 시그널 핸들링이 불가능
Out-of-band 데이터 수신도 예외상황이므로, select() 써서 대체 가능
writev, readv에 대응하는 함수는 윈도우에 없음.
대신 윈도우에선 중첩 입출력(Overlapped IO)를 이용할 수 있음.
멀티캐스트는 UDP 기반.
TTL (Time to Live)
IP_MULTICAST_TTL 옵션에서 TTL 설정 가능멀티캐스트 그룹 가입
IP_ADD_MEMBERSHIP 옵션에서 가입 가능ip_mreq에 가입할 그룹의 IP 주소 정보 및 소켓이 속한 호스트의 IP 주소 명시멀티캐스트에서 서버는 Sender, 클라는 Receiver라 한다
send_sock=socket(PF_INET, SOCK_DGRAM, 0);
memset(&mul_adr, 0, sizeof(mul_adr));
mul_adr.sin_family=AF_INET;
mul_adr.sin_addr.s_addr=inet_addr(argv[1]); // Multicast IP
mul_adr.sin_port=htons(atoi(argv[2])); // Multicast Port
setsockopt(send_sock, IPPROTO_IP, IP_MULTICAST_TTL,
(void*)&time_live, sizeof(time_live));
if((fp=fopen("news.txt", "r"))==NULL)
error_handling("fopen() error");
while(!feof(fp))
{
fgets(buf, BUF_SIZE, fp);
sendto(send_sock, buf, strlen(buf), 0,
(struct sockaddr*)&mul_adr, sizeof(mul_adr));
sleep(2);
}
fclose(fp);
close(send_sock);
return 0;
Sender.c
recv_sock=socket(PF_INET, SOCK_DGRAM, 0);
memset(&adr, 0, sizeof(adr));
adr.sin_family=AF_INET;
adr.sin_addr.s_addr=htonl(INADDR_ANY);
adr.sin_port=htons(atoi(argv[2]));
if(bind(recv_sock, (struct sockaddr*) &adr, sizeof(adr))==-1)
error_handling("bind() error");
join_adr.imr_multiaddr.s_addr=inet_addr(argv[1]);
join_adr.imr_interface.s_addr=htonl(INADDR_ANY);
setsockopt(recv_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*)&join_adr, sizeof(join_adr));
while(1)
{
str_len=recvfrom(recv_sock, buf, BUF_SIZE-1, 0, NULL, 0);
if(str_len<0)
break;
buf[str_len]=0;
fputs(buf, stdout);
}
Receiver.c

멀티캐스트 : 서로 다른 네트워크라도 그룹에 가입만 됐으면 데이터 수신 가능
브로드캐스트 : 동일한 네트워크 호스트로만 전송 대상 제한
192.12.34 네트워크 모든 호스트 → 192.12.34.255255.255.255.255로 전송하면 자신이 연결된 네트워크 모든 호스트에게 전달#include<string.h>
#include<vector>
#include<iostream>
#include<queue>
#include<map>
#include <tuple>
using namespace std;
typedef pair<int, int> pii;
typedef vector<pii> vp;
typedef pair<pii, int> ppii;
namespace
{
int w, h;
char room[20][20];
int checked[20][20][1 << 10];
pii start;
vp dust;
map<pii, int> bitMap;
vp dirs = { {0,1},{0,-1},{1,0},{-1,0} };
int FindMinCourse()
{
// bfs 때리는데, 같은 비트마스크 이미 있으면 넘어가기
// qsize만큼만 돌린 뒤 count 하나 올리기
memset(checked, 0, sizeof(checked));
int cnt = 0;
queue<ppii> q;
int bitMask = 0;
q.push({ start, bitMask });
checked[start.first][start.second][bitMask] = true;
while (!q.empty())
{
int qsize = q.size();
while(qsize--)
{
int i, j;
tie(i, j) = q.front().first;
bitMask = q.front().second;
q.pop();
// 1 << dust.size()를 괄호로 감싸야 했다
if (bitMask == ((1 << dust.size()) - 1)) return cnt;
for (pii dir : dirs)
{
int newi = i + dir.first;
int newj = j + dir.second;
int newBitMask = bitMask;
if (newi < 0 || h <= newi || newj < 0 || w <= newj) continue;
if (room[newi][newj] == 'x') continue;
if (room[newi][newj] == '*') newBitMask |= 1 << bitMap[{newi, newj}];
if (checked[newi][newj][newBitMask]) continue;
checked[newi][newj][newBitMask] = true;
q.push({ {newi,newj},newBitMask });
}
}
cnt++;
}
return -1;
}
}
int main()
{
cin.tie(0);
cout.tie(0);
while (1)
{
cin >> w >> h;
if (w == 0) break;
dust = vp();
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
cin >> room[i][j];
if (room[i][j] == '*')
{
dust.push_back({ i,j });
bitMap[{i, j}] = dust.size() - 1;
}
else if (room[i][j] == 'o')
{
start = { i,j };
}
}
}
cout << FindMinCourse() << '\n';
}
}
답지 보고 이해한 후에 실수한 거 gpt로 찾기까지 하면서 품
<string.h>가 들어가야 한다room[newi][newj] 들어갈 자리에 room[i][j] 넣는 실수'*'이면 dust에 넣어야 하는데, 'x'면 넣어버리는 실수bitMap에 dust.size() -1 해야 하는데 개수대로 넣으면 되겠지~ 하고 -1 누락한 실수