기능
스트림을 반만 닫아줄 수 있다.
헤더
WinSock2.h
형태
int shudown(SOCKET s, int how);
리턴
성공 시 0, 실패 시 SOCKET_ERROR
매개변수
s: half-close 할 소켓의 핸들
how: 종료 모드
상수값 |
모드 |
정의 |
0 |
SD_RECEIVE |
입력 스트림 종료 |
1 |
SD_SEND |
출력 스트림 종료 |
2 |
SD_BOTH |
입출력 스트림 종료 |
예제(파일 전송)
서버
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <WinSock2.h>
#define BUFSIZE 30
void ErrorHandling(char *message);
int main(int argc, char **argv) {
WSADATA wsaData;
SOCKET hServSock;
SOCKET hClntSock;
char buf[BUFSIZE];
FILE* fp;
SOCKADDR_IN servAddr;
SOCKADDR_IN clntAddr;
int clntAddrSize;
int len;
if (argc != 2) {
printf("Usage: %s <port>\n", argv[0]);
exit(1);
}
/* 접속해 오는 클라이언트에게 전송해 줄 파일 오픈 */
fp = fopen("ctest.c", "r");
if (fp == NULL)
ErrorHandling("File open error!");
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) /* Load WinSock 2.2 DLL */
ErrorHandling("WSAStartup() error!");
/* 서버 접속을 위한 소켓 생성 */
hServSock = socket(PF_INET, SOCK_STREAM, 0);
if (hServSock == INVALID_SOCKET)
ErrorHandling("socket() error!");
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(atoi(argv[1]));
if(bind(hServSock, (SOCKADDR*) &servAddr, sizeof(servAddr))== SOCKET_ERROR)
ErrorHandling("bind() error!");
if(listen(hServSock, 5)==SOCKET_ERROR)
ErrorHandling("listen() error!");
clntAddrSize = sizeof(clntAddr);
hClntSock = accept(hServSock, (SOCKADDR*)&clntAddr, &clntAddrSize);
if (hClntSock == INVALID_SOCKET)
ErrorHandling("accept() error!");
/* 클라이언트에 데이터 전송 */
while (1) {
len = fread(buf, sizeof(char), BUFSIZE, fp);
send(hClntSock, buf, len, 0);
if (feof(fp))
break;
}
/* 데이터 전송 후 소켓의 일부 (전송영역) 를 닫음 */
if (shutdown(hClntSock, SD_SEND) == SOCKET_ERROR)
ErrorHandling("shutdown error!");
/* 인사의 메시지를 수신 */
len = recv(hClntSock, buf, BUFSIZE - 1, 0);
buf[len] = 0;
fputs(buf, stdout);
fclose(fp);
closesocket(hClntSock);
WSACleanup();
return 0;
}
void ErrorHandling(char *message) {
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
클라이언트
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <WinSock2.h>
#define BUFSIZE 30
void ErrorHandling(char *message);
int main(int argc, char **argv) {
WSADATA wsaData;
SOCKET hSocket;
char buf[BUFSIZE];
FILE* fp;
SOCKADDR_IN servAddr;
int len;
if (argc != 3) {
printf("Usage: %s <IP> <port>\n", argv[0]);
exit(1);
}
fp = fopen("receive.dat", "w");
if (fp == NULL)
ErrorHandling("File open error!");
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) /* Load WinSock 2.2 DLL */
ErrorHandling("WSAStartup() error!");
/* 서버 접속을 위한 소켓 생성 */
hSocket = socket(PF_INET, SOCK_STREAM, 0);
if (hSocket == INVALID_SOCKET)
ErrorHandling("socket() error!");
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr(argv[1]);
servAddr.sin_port = htons(atoi(argv[2]));
if (connect(hSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) /* 서버로 연결 요청 */
ErrorHandling("connect() error!");
/* 데이터를 전송받아서 파일에 저장한다. */
while ((len=recv(hSocket, buf, BUFSIZE, 0)) !=0) {
fwrite(buf, sizeof(char), len, fp);
}
/* 전송해 준 것에 대한 감사의 메시지 전달 */
send(hSocket, "Thank you\n", 10, 0);
fclose(fp);
closesocket(hSocket); /* 연결 종료 */
WSACleanup();
return 0;
}
void ErrorHandling(char *message) {
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
'컴퓨터' 카테고리의 다른 글
hostent (0) | 2019.03.16 |
---|---|
gethostbyname (0) | 2019.03.16 |
strcmp (0) | 2019.03.15 |
네트워크 프로토콜과 계층구조 (0) | 2019.03.13 |
npm 사용법 (0) | 2019.03.11 |