초보 socket 프로 그래 밍 입문 상세 안내
운영 플랫폼:Ubantu 14.04 LTS
질문 안내
질문 1:헤더 파일 의 질문:
4.567914 와 4.567914 는 어떤 차이 가 있 습 니까?
해답:
1.diff 로 보기:adc 는 각각 추가,삭제,수정 을 표시 합 니 다.
2.사실은 경로 가 다 르 기 때문에 서로 다른 socke.h 파일 이 있 습 니 다.
3.
4.
질문 2:대소 단자 바이트 순서 문제:
1.c 언어 검 측:포인터 수치 와 주소 의 교차 응용 을 이용 하여 네트워크 이식 성 을 강화 합 니 다.
2.socket 은 바이트 순서 변환 함 수 를 제공 합 니 다:h:host;n:network;l:log 32 비트;s:short 16 비트
3.htonl:호스트 의 32 비트 호스트 바이트 순서(ip 주소)를 네트워크 바이트 순서(열 데이터)로 변환 합 니 다.
문제 3:한 서버,한 클 라 이언 트 에 대해 다음 과 같은 대응 하 는 역할 설 이 있다.
대상 우선
대상 second
서버
클 라 이언 트
감청 자
방송 자
서 비 스 를 제공 하 다
요청 서비스
socket 프로 그래 밍 전체 과정 분석:
작성 및 삭제
서버 와 클 라 이언 트 는 같은 socket 채널 을 통 해 통신 하고 socket 채널 을 만들어 socket 연결 을 제공 합 니 다.
#include <sys/socket.h>
domain(도 메 인):각 도 메 인 에서 AFXXX 명령어떤 주소 형식 을 사용 할 지 결정 하고 통신 특성 을 확인 합 니 다:주소 형식 포함type:바이트 의 종 류 를 확인 하고 자 유 롭 게 종 류 를 추가 할 수 있 습 니 다.
상용:SOCKSTREAM(즉:TCP)과 SOCKDGRAM(즉:UDP)
protocol:socket 에서 사용 하 는 전송 프로 토 콜 번 호 를 지정 합 니 다.일반적으로 0 으로 직접 설정 하면 됩 니 다.이 는 주어진 도 메 인 과 소켓 형식 으로 기본 전송 프로 토 콜 을 선택 하 는 것 을 의미 합 니 다.
반환 값:소켓 처리 코드 를 정확하게 되 돌려 줍 니 다.이 수 치 는 저장 해서 사용 할 것 이다.
서버 와 클 라 이언 트 모두 가능 합 니 다.socket 통신 IO 를 닫 습 니 다.
#include <linux/socket.h>
s:대표 socketfd,닫 아야 할 소켓 파일 설명자방법
shutdown 은 socket 채널 을 비활성 상태 로 만 듭 니 다.이 채널 은 쓰기 단 을 닫 고 이 소켓 읽 기 단 을 계속 받 아 데이터 가 언제 끝 날 지 확인 한 다음 close 를 사용 하여 이 채널 을 닫 을 수 있 습 니 다.
연결 관계
IO 를 만 들 거나 소각 하거나 닫 은 후에 목표 통신 프로 세 스 를 어떻게 표시 하 는 지 알 아야 합 니 다.
원인:네트워크 에는 여러 개의 컴퓨터 가 있 고,한 컴퓨터 에 여러 개의 프로그램(프로 세 스)이 실행 되 고 있다.다음은 2 층 관계 입 니 다.
1)대상 컴퓨터 의 네트워크 주소
2)대상 컴퓨터 의 대상 프로 세 스 가 대표 하 는 포트 번호
그래서 지금 당신 이 알 아야 할 것 은 다음 과 같은 몇 가지 가 있 습 니 다.
1.바이트 순서:위의 문제 2 를 직접 보면 되 고 관 계 를 간단하게 전환 할 수 있다.
2.주소 형식:서로 다른 인터넷 주소 에 따라
3.주소 구조 체 를 정의 하고 실제 불 러 오 는 수치 에 따라 socket API 실 참 으로 합 니 다.
4.주소 진 변환:주 소 를 바 이 너 리 와 텍스트 문자열 형식 으로 변환 합 니 다.inet_ntop 또는 inetpton
바 인 딩 이 어 서버 에 서 는 바 인 딩(관련)주소 와 소켓 이 필요 합 니 다.주어진 sockfd 에 sockaddr 구조 데 이 터 를 연결 합 니 다.서버 에서 소켓 을(도 메 인)주소 에 연결 해 야 클 라 이언 트 가 연결(connect)에 성공 할 수 있 습 니 다.
int socket(int domain,int type,int protocol);
sockfd:소켓 파일 설명자,socket 에서 돌아 오 는 값 입 니 다.my_addr:(서버)네트워크 주소 정보
반환 값:정확 한 바 인 딩 주소 와 소켓 여 부 를 판단 합 니 다.
연결 하기 전에 소켓(socket)을 만 들 고 연결 기반(bid)을 만 들 었 습 니 다.그렇다면 통신 에 앞서 socket 채널 을 연결 하기 위 한 것 이다.
int shutdown(int s,int how);
sockfd:소켓 파일 설명자,socket 에서 돌아 오 는 값 입 니 다.serv_addr:네트워크 주소 정보
반환 값:정확 한 연결 여 부 를 판단 하려 면 클 라 이언 트 프로그램 이 connect 가 되 돌아 오 는 오 류 를 처리 해 야 합 니 다.
지금까지 connect 함수 의 매개 변수 유형 과 개 수 는 모두 bid 와 같다 는 것 을 발 견 했 을 지도 모른다.
TCPIP 프로 토 콜 에 따라 연결 해 야 할 정보:IP 주소,포트 번호 만으로 도 충분 합 니 다.나머지 MAC 주소 등 은 socket 안에 있 으 니 신경 쓸 필요 가 없습니다.
감청 에 주의해 야 할 것 은 이런 연결 은 서버 에서 어떤 클 라 이언 트 가 연결 을 요청 하 는 지 확인 해 야 한 다 는 것 이다.따라서 서버 는 먼저 실행 요청 클 라 이언 트(임의의)연결 상태 에 들 어가 listen(감청)상태 에 들 어 갑 니 다.사용 함수:
int bind(int sockfd,struct sockaddr * my_addr,int addrlen);
s:서버 소켓 설명자,socket 에서 돌아 오 는 값 입 니 다.backlog:동시에 처리 할 수 있 는 최대 연결 요 구 를 지정 합 니 다.
함수 반환 값:감청 상태 에 올 바 르 게 들 어 갔 는 지 여부
연결 할 때 서버 는 이미 listen 상태 에 들 어 갔 고 이어서 호출 되 었 습 니 다.
int connect (int sockfd,struct sockaddr * serv_addr,int addrlen);
s:서버 소켓 설명자,socket 에서 돌아 오 는 값 입 니 다.addr:연 결 된 클 라 이언 트 의 소켓 데이터
addrlen:연 결 된 클 라 이언 트 의 소켓 데이터 길이
복귀:연 결 된 클 라 이언 트 의 파일 설명자
데이터 읽 기 및 전송
지금까지 서버 와 클 라 이언 트 는 양 방향 통신 의 기초 준 비 를 마 쳤 다.
send 와 recv 는 잠시 언급 하지 않 고 독자 스스로 API 를 찾 습 니 다.
int recv(int s,void *buf,int len,unsigned int flags);
int send(int s,const void * msg,int len,unsigned int falgs);
다음은 코드 와 직접 연 결 됩 니 다.
// and socket
#include <stdio.h> //
#include <stdlib.h> //
#include <errno.h> //errno
#include <unistd.h> //
#include <stddef.h> //
#include <sys/socket.h> // socket API
#include <sys/un.h> //
#include <sys/types.h> //socket API
#include <arpa/inet.h> //
#include <netinet/in.h> // ( )、
클 라 이언 트 코드:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <pthread.h>
#include "wrap.h"
#define MAXLINE 80
#define SERV_PORT 8000
int main(int argc, char *argv[])
{
struct sockaddr_in servaddr;
char buf[MAXLINE];
int sockfd, n;
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
inet_pton(AF_INET, "192.168.191.6", &servaddr.sin_addr);
servaddr.sin_port = htons(SERV_PORT);
Connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
while (fgets(buf, MAXLINE, stdin) != NULL) {
Write(sockfd, buf, strlen(buf));
n = Read(sockfd, buf, MAXLINE);
if (n == 0)
printf("the other side has been closed.
");
else
Write(STDOUT_FILENO, buf, n);
}
Close(sockfd);
return 0;
}
서버 코드:
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include "wrap.h"
#define MAXLINE 80
#define SERV_PORT 8000
int main(void)
{
struct sockaddr_in servaddr, cliaddr;
socklen_t cliaddr_len;
int listenfd, connfd;
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];
int i, n;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("192.168.191.6");
servaddr.sin_port = htons(SERV_PORT);
Bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
Listen(listenfd, 20);
printf("Accepting connections ...
");
while (1) {
cliaddr_len = sizeof(cliaddr);
connfd = Accept(listenfd,
(struct sockaddr *) &cliaddr,
&cliaddr_len);
while (1) {
n = Read(connfd, buf, MAXLINE);
if (n == 0) {
printf("the other side has been closed.
");
break;
}
printf("received from %s at PORT %d
",
(char *)inet_ntop(AF_INET,
&cliaddr.sin_addr, str,
sizeof(str)),
(int)ntohs(cliaddr.sin_port));
for (i = 0; i < n; i++)
buf[i] = toupper(buf[i]);
Write(connfd, buf, n);
}
Close(connfd);
}
}
실행 결과:
hhc@my:~/sharefile/socket/tcp$ ./server &
[1] 15371
hhc@my:~/sharefile/socket/tcp$ Accepting connections ...
hhc@my:~/sharefile/socket/tcp$ ./client
this is a test!
received from 192.168.191.6 at PORT 53685
THIS IS A TEST!
개인 패키지 socket 인터페이스 함수:
#include "wrap.h"
void perr_exit(const char *s)
{
perror(s);
exit(1);
}
int Accept(int fd, struct sockaddr *sa, socklen_t * salenptr)
{
int n;
again:
if ((n = accept(fd, sa, salenptr)) < 0) {
if ((errno == ECONNABORTED) || (errno == EINTR))
goto again;
else
perr_exit("accept error");
}
return n;
}
void Bind(int fd, const struct sockaddr *sa, socklen_t salen)
{
if (bind(fd, sa, salen) < 0)
perr_exit("bind error");
}
void Connect(int fd, const struct sockaddr *sa, socklen_t salen)
{
if (connect(fd, sa, salen) < 0)
perr_exit("connect error");
}
void Listen(int fd, int backlog)
{
if (listen(fd, backlog) < 0)
perr_exit("listen error");
}
int Socket(int family, int type, int protocol)
{
int n;
if ((n = socket(family, type, protocol)) < 0)
perr_exit("socket error");
return n;
}
ssize_t Read(int fd, void *ptr, size_t nbytes)
{
ssize_t n;
again:
if ((n = read(fd, ptr, nbytes)) == -1) {
if (errno == EINTR)
goto again;
else
return -1;
}
return n;
}
ssize_t Write(int fd, const void *ptr, size_t nbytes)
{
ssize_t n;
again:
if ((n = write(fd, ptr, nbytes)) == -1) {
if (errno == EINTR)
goto again;
else
return -1;
}
return n;
}
void Close(int fd)
{
if (close(fd) == -1)
perr_exit("close error");
}
ssize_t Readn(int fd, void *vptr, size_t n)
{
size_t nleft;
ssize_t nread;
char *ptr;
ptr = vptr;
nleft = n;
while (nleft > 0) {
if ((nread = read(fd, ptr, nleft)) < 0) {
if (errno == EINTR)
nread = 0;
else
return -1;
} else if (nread == 0)
break;
nleft -= nread;
ptr += nread;
}
return n - nleft;
}
ssize_t Writen(int fd, const void *vptr, size_t n)
{
size_t nleft;
ssize_t nwritten;
const char *ptr;
ptr = vptr;
nleft = n;
while (nleft > 0) {
if ((nwritten = write(fd, ptr, nleft)) <= 0) {
if (nwritten < 0 && errno == EINTR)
nwritten = 0;
else
return -1;
}
nleft -= nwritten;
ptr += nwritten;
}
return n;
}
ssize_t my_read(int fd, char *ptr)
{
static int read_cnt;
static char *read_ptr;
static char read_buf[100];
if (read_cnt <= 0) {
again:
if ((read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {
if (errno == EINTR)
goto again;
return -1;
} else if (read_cnt == 0)
return 0;
read_ptr = read_buf;
}
read_cnt--;
*ptr = *read_ptr++;
return 1;
}
ssize_t Readline(int fd, void *vptr, size_t maxlen)
{
ssize_t n, rc;
char c, *ptr;
ptr = vptr;
for (n = (ssize_t)1; n < (ssize_t)maxlen; n++) {
if ((rc = my_read(fd, &c)) == 1) {
*ptr++ = c;
if (c == '
')
break;
} else if (rc == 0) {
*ptr = 0;
return n - 1;
} else
return -1;
}
*ptr = 0;
return n;
}
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
React 구성 요소에서 소켓 이벤트 리스너가 여러 번 실행됩니다.기본적이지만 종종 간과되는 사이드 프로젝트를 하면서 배운 것이 있습니다. 이 프로젝트에는 단순히 두 가지 주요 부분이 포함되어 있습니다. 프런트 엔드: 반응 및 재료 UI 백엔드: Express, Typescript...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.