TCP 기반 데이터에는 경계가 존재하지 않는다.
UDP 기반 데이터는 경계가 존재한다.
UDP 소켓이 전송하는 패킷을 데이터그램이라고 한다.
UDP 소켓에는 데이터를 전송할 목적지와 PORT 번호를 등록하지 않는다.
때문에 sendto 함수호출을 통한 데이터의 전송 과정은 이렇다
목적지가 등록되면 connected 소켓, 없으면 unconnected 소켓이라 부른다
close()로 연결 종료하면 이후에 오는 데이터는 못 받는다.
shutdown()으로 일부만 종료(Half-close)하면 전송 혹은 수신 한 쪽만 닫을 수 있다.
전송 끝났다는 의미로 EOF 보내려면, 그리고 이후에 오는 메시지 받으려면 Half-close 필요하다.
fp=fopen("file_server.c", "rb");
(...)
while(1)
{
read_cnt=fread((void*)buf, 1, BUF_SIZE, fp);
if(read_cnt<BUF_SIZE)
{
write(clnt_sd, buf, read_cnt);
break;
}
write(clnt_sd, buf, BUF_SIZE);
}
shutdown(clnt_sd, SHUT_WR);
read(clnt_sd, buf, BUF_SIZE);
printf("Message from client: %s \n", buf);
파일을 연 뒤 읽어서 클라에게 보내준 후 "Thank you"를 기다리는 서버 코드
shutdown()으로 발신은 끊지만 수신은 열어둔다
fp=fopen("receive.dat", "wb");
(...)
connect(sd, (struct sockaddr*)&serv_adr, sizeof(serv_adr));
while((read_cnt=read(sd, buf, BUF_SIZE))!=0)
fwrite((void*)buf, 1, read_cnt, fp);
puts("Received file data");
write(sd, "Thank you", 10);
파일을 받아서 receive.dat에 저장한 뒤 "Thank you"를 보내는 클라 코드

shutdown()은 동일하지만 전달할 상수 이름이 약간 다르다
vector<int> solution(vector<string> operations) {
vector<int> answer = vector<int>(2,0);
map<int, int> scale;
priority_queue<int> maxH;
priority_queue<int, vector<int>, greater<int>> minH;
int count = 0;
int del;
for(string op : operations)
{
// 최소힙을 왼쪽, 최대힙을 오른쪽으로 생각하고, 딕셔너리로 숫자를
// 값을 삭제했을 때, 삭제하지 않은 쪽 힙으로 숫자가 기울어진다
// 값을 삭제하기 전에, 딕셔너리에서 해당 값을 확인하고, 숫자만큼 균형을 맞춘다
if(op[0] == 'I') // 주어진 숫자 삽입
{
int val = atoi(op.substr(2).c_str());
minH.push(val);
maxH.push(val);
count++;
}
else if(op[0] == 'D' && count > 0)
{
if(op[2] == '1') // 최댓값 삭제
{
while(scale[maxH.top()]>0) // 최소힙에서 해당 숫자를 이미 지워버렸을 때
{
del = maxH.top(); maxH.pop();
scale[del]--;
}
del = maxH.top(); maxH.pop();
scale[del]--;
}
else // 최솟값 삭제
{
while(scale[minH.top()]<0) // 최대힙에서 해당 숫자를 이미 지워버렸을 때
{
del = minH.top(); minH.pop();
scale[del]++;
}
del = minH.top(); minH.pop();
scale[del]++;
}
count--;
}
}
if(count>0)
{
while(scale[maxH.top()]>0) // 최소힙에서 해당 숫자를 이미 지워버렸을 때
{
del = maxH.top(); maxH.pop();
scale[del]--;
}
while(scale[minH.top()]<0) // 최대힙에서 해당 숫자를 이미 지워버렸을 때
{
del = minH.top(); minH.pop();
scale[del]++;
}
answer[1] = minH.top();
answer[0] = maxH.top();
}
return answer;
}
leetcode에서 못 풀고 답지 봤었던 것 같은 기억이 있어서 그거 살려서 풀었다
atoi() 대신 stoi() 쓰면 c_str() 안 써도 된다. 애초에 atoi()는 <string>에 안들어있음.#include"4991.h"
using namespace std;
typedef pair<int, int> pii;
typedef vector<pii> vp;
typedef vector<char> vc;
typedef vector<vc> vvc;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef map<pii, int> mp;
typedef vector<int> vi;
typedef vector<vi> vvi;
namespace
{
vi dirx = { 0,0,1,-1 };
vi diry = { 1,-1,0,0 };
void CheckCost(pii sp, vvc& room, mp& idxMap, vvi& d2d, int w, int h)
{
queue<pii> q;
vvb visited = vvb(h, vb(w, false));
q.push(sp);
visited[sp.first][sp.second] = true;
int spIdx = idxMap[{sp.first, sp.second}];
int dist = 1;
while (!q.empty())
{
int qlen = size(q);
while (qlen--)
{
pii qf = q.front(); q.pop();
for (int i = 0; i < 4; i++)
{
int newi = qf.first + dirx[i];
int newj = qf.second + diry[i];
if (newi < 0 || h <= newi || newj < 0 || w <= newj) continue;
if (visited[newi][newj]) continue;
visited[newi][newj] = true;
q.push({ newi,newj });
if (room[newi][newj] == '*' || room[newi][newj] == 'o')
{
int newpIdx = idxMap[{newi, newj}];
d2d[spIdx][newpIdx] = dist;
d2d[newpIdx][spIdx] = dist;
}
}
}
dist++;
}
}
int MinCostSum(vp& dirties, vvi& d2d, mp& idxMap, int w, int h)
{
// dirties의 순열을 만든다
// 시작 > 순열 각 원소의 다음 원소에 대해 방문 비용 더한다
vector<int> perm;
while(size(perm)<size(dirties))
{
for(int i=0; i<)
if()
{
break;
}
}
}
}
void B4991::Solution()
{
int w, h;
pii startp; // 시작 위치
mp idxMap; // 각 더러운 칸을 인덱스로 변환
vp dirties; // 각 더러운 칸 저장
vvi d2d; // 각 더러운 칸에서 다른 더러운 칸으로 가는 비용
vvc room; // 전체 맵
while (1)
{
cin >> w >> h;
if (w == 0) break;
room = vvc(h, vc(w));
dirties = vp();
idxMap = mp();
int dirtyIdx = 0;
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
cin >> room[i][j];
if (room[i][j] == '*')
{
pii newDirty = { i,j };
dirties.push_back(newDirty);
idxMap[newDirty] = dirtyIdx;
dirtyIdx++;
}
else if (room[i][j] == 'o')
{
startp = { i,j };
}
}
}
idxMap[startp] = dirtyIdx;
d2d = vvi(dirtyIdx+1, vi(dirtyIdx+1));
// 각 더러운 칸에 대해 bfs를 한다
// 더러운 칸 방문 순서로 순열을 만든다
// bfs 결과를 순열 합계값으로 만들고 최솟값을 갱신한다
CheckCost(startp, room, idxMap, d2d, w, h);
for (pii dirty : dirties) CheckCost(dirty,room, idxMap, d2d,w,h);
int minCost = MinCostSum(dirties,d2d,idxMap,w,h);
cout << "tes";
}
}
일단 여기까지. 내일 마저.
순열 만들려다가 설마 이딴 풀이가 정답일리 없을 것 같아서 정답을 찾아봤는데 이게 맞는 접근이었다.