libuv 학습 노트 5------TCP 클라이언트의 실현
TCP 클라이언트의 기본 단계는 다음과 같습니다.
1.
uv_tcp_init
tcp 핸들 만들기2.uv_tcp_connect tcp 연결 만들기
3.stream 조작을 사용하여 클라이언트와 통신하기
사용된 API는 다음과 같습니다.
1.uv_tcp_init
2.uv_ip4_addr
3.uv_tcp_connect
4.uv_write/uv_read_start
TCP 클라이언트의 구현만을 위한 새로운 API 함수 uv_ 소개tcp_connect.
1.uv_tcp_connect 함수 설명
int uv_tcp_connect(uv_connect_t* req,uv_tcp_t* handle,const struct sockaddr* addr,uv_connect_cb cb);
매개변수 1: 요청 객체 연결
매개변수 2: TCP 클라이언트 객체
매개 변수 3: 채워진structsockaddr_구조체
매개변수 4: 콜백 함수struct sockaddr_in addr;
uv_connect_t* connect = (uv_connect_t*)malloc(sizeof(uv_connect_t));
uv_ip4_addr("192.168.65.205",DEFAULT_PORT,&addr);
int r = uv_tcp_connect(connect,&mysocket,(const struct sockaddr*)&addr,on_connect);
if(r)
{
fprintf(stderr, "connect error %s
", uv_strerror(r));
return 1;
}
2.uv_tcp_connect 리셋 함수 소개
void (*uv_connect_cb)(uv_connect_t* req, int status);
연결 성공/실패 후 이 함수를 호출합니다.
status: 되돌아오는 상태입니다. 0보다 작으면 오류가 발생합니다.
req: 연결 요청 대상, req->handle는 TCP 클라이언트 대상(mysocket)을 가리키며, req->handle를 uv_에 직접 사용할 수 있습니다write,uv_read_start 등류 작업 중입니다.
3. 지정한 파일을 서버에 전송하는 코드 구현 #include
#include
#include
uv_loop_t *loop;
#define DEFAULT_PORT 7000
uv_tcp_t mysocket;
char *path = NULL;
uv_buf_t iov;
char buffer[128];
uv_fs_t read_req;
uv_fs_t open_req;
void on_read(uv_fs_t *req);
void on_write(uv_write_t* req, int status)
{
if (status < 0)
{
fprintf(stderr, "Write error: %s
", uv_strerror(status));
uv_fs_t close_req;
uv_fs_close(uv_default_loop(), &close_req, open_req.result, NULL);
uv_close((uv_handle_t *)&mysocket,NULL);
exit(-1);
}
else
{
uv_fs_read(uv_default_loop(), &read_req, open_req.result, &iov, 1, -1, on_read);
}
}
void on_read(uv_fs_t *req)
{
if (req->result < 0)
{
fprintf(stderr, "Read error: %s
", uv_strerror(req->result));
}
else if (req->result == 0)
{
uv_fs_t close_req;
// synchronous
uv_fs_close(uv_default_loop(), &close_req, open_req.result, NULL);
uv_close((uv_handle_t *)&mysocket,NULL);
}
else
{
iov.len = req->result;
uv_write((uv_write_t *)req,(uv_stream_t *)&mysocket,&iov,1,on_write);
}
}
void on_open(uv_fs_t *req)
{
if (req->result >= 0)
{
iov = uv_buf_init(buffer, sizeof(buffer));
uv_fs_read(uv_default_loop(), &read_req, req->result,&iov, 1, -1, on_read);
}
else
{
fprintf(stderr, "error opening file: %s
", uv_strerror((int)req->result));
uv_close((uv_handle_t *)&mysocket,NULL);
exit(-1);
}
}
void on_connect(uv_connect_t* req, int status)
{
if(status < 0)
{
fprintf(stderr,"Connection error %s
",uv_strerror(status));
return;
}
fprintf(stdout,"Connect ok
");
uv_fs_open(loop,&open_req,path,O_RDONLY,-1,on_open);
}
int main(int argc,char **argv)
{
if(argc < 2)
{
fprintf(stderr,"Invaild argument!
");
exit(1);
}
loop = uv_default_loop();
path = argv[1];
uv_tcp_init(loop,&mysocket);
struct sockaddr_in addr;
uv_connect_t* connect = (uv_connect_t*)malloc(sizeof(uv_connect_t));
uv_ip4_addr("127.0.0.1",DEFAULT_PORT,&addr);
int r = uv_tcp_connect(connect,&mysocket,(const struct sockaddr *)&addr,on_connect);
if(r)
{
fprintf(stderr, "connect error %s
", uv_strerror(r));
return 1;
}
return uv_run(loop,UV_RUN_DEFAULT);
}
이 코드는 libuv 파일 조작, 흐름 조작, TCP 실현 등 지식을 이용했다.코드의 기본 논리는 다음과 같습니다.
1. TCP 클라이언트 객체와 TCP 연결 요청 객체를 만들고 서버와 연결합니다.
2. 연결에 성공하면 전송할 파일을 엽니다.
3. 파일을 열면 일정한 파일 내용을 읽고 읽으면 파일 내용을stream 조작을 이용하여 서버에 보냅니다.
4. 전송에 성공하면 파일 내용을 다시 읽고 읽기에 성공하면 서버에 보냅니다.
5. 파일 끝까지 읽을 때까지 4단계로 반복합니다.
6. 파일을 닫고 흐름을 닫습니다.
테스트:
1. 서버를 열고 7000 포트를 감청하고 출력을 파일로 바꿉니다.
nc -l 7000 > test_recv.jpg
2. 프로그램을 컴파일하고 실행합니다.
gcc main.c -luv
./a.out test.jpg
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSON
JSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다.
그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다.
저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.
struct sockaddr_in addr;
uv_connect_t* connect = (uv_connect_t*)malloc(sizeof(uv_connect_t));
uv_ip4_addr("192.168.65.205",DEFAULT_PORT,&addr);
int r = uv_tcp_connect(connect,&mysocket,(const struct sockaddr*)&addr,on_connect);
if(r)
{
fprintf(stderr, "connect error %s
", uv_strerror(r));
return 1;
}
void (*uv_connect_cb)(uv_connect_t* req, int status);
연결 성공/실패 후 이 함수를 호출합니다.
status: 되돌아오는 상태입니다. 0보다 작으면 오류가 발생합니다.
req: 연결 요청 대상, req->handle는 TCP 클라이언트 대상(mysocket)을 가리키며, req->handle를 uv_에 직접 사용할 수 있습니다write,uv_read_start 등류 작업 중입니다.
3. 지정한 파일을 서버에 전송하는 코드 구현 #include
#include
#include
uv_loop_t *loop;
#define DEFAULT_PORT 7000
uv_tcp_t mysocket;
char *path = NULL;
uv_buf_t iov;
char buffer[128];
uv_fs_t read_req;
uv_fs_t open_req;
void on_read(uv_fs_t *req);
void on_write(uv_write_t* req, int status)
{
if (status < 0)
{
fprintf(stderr, "Write error: %s
", uv_strerror(status));
uv_fs_t close_req;
uv_fs_close(uv_default_loop(), &close_req, open_req.result, NULL);
uv_close((uv_handle_t *)&mysocket,NULL);
exit(-1);
}
else
{
uv_fs_read(uv_default_loop(), &read_req, open_req.result, &iov, 1, -1, on_read);
}
}
void on_read(uv_fs_t *req)
{
if (req->result < 0)
{
fprintf(stderr, "Read error: %s
", uv_strerror(req->result));
}
else if (req->result == 0)
{
uv_fs_t close_req;
// synchronous
uv_fs_close(uv_default_loop(), &close_req, open_req.result, NULL);
uv_close((uv_handle_t *)&mysocket,NULL);
}
else
{
iov.len = req->result;
uv_write((uv_write_t *)req,(uv_stream_t *)&mysocket,&iov,1,on_write);
}
}
void on_open(uv_fs_t *req)
{
if (req->result >= 0)
{
iov = uv_buf_init(buffer, sizeof(buffer));
uv_fs_read(uv_default_loop(), &read_req, req->result,&iov, 1, -1, on_read);
}
else
{
fprintf(stderr, "error opening file: %s
", uv_strerror((int)req->result));
uv_close((uv_handle_t *)&mysocket,NULL);
exit(-1);
}
}
void on_connect(uv_connect_t* req, int status)
{
if(status < 0)
{
fprintf(stderr,"Connection error %s
",uv_strerror(status));
return;
}
fprintf(stdout,"Connect ok
");
uv_fs_open(loop,&open_req,path,O_RDONLY,-1,on_open);
}
int main(int argc,char **argv)
{
if(argc < 2)
{
fprintf(stderr,"Invaild argument!
");
exit(1);
}
loop = uv_default_loop();
path = argv[1];
uv_tcp_init(loop,&mysocket);
struct sockaddr_in addr;
uv_connect_t* connect = (uv_connect_t*)malloc(sizeof(uv_connect_t));
uv_ip4_addr("127.0.0.1",DEFAULT_PORT,&addr);
int r = uv_tcp_connect(connect,&mysocket,(const struct sockaddr *)&addr,on_connect);
if(r)
{
fprintf(stderr, "connect error %s
", uv_strerror(r));
return 1;
}
return uv_run(loop,UV_RUN_DEFAULT);
}
이 코드는 libuv 파일 조작, 흐름 조작, TCP 실현 등 지식을 이용했다.코드의 기본 논리는 다음과 같습니다.
1. TCP 클라이언트 객체와 TCP 연결 요청 객체를 만들고 서버와 연결합니다.
2. 연결에 성공하면 전송할 파일을 엽니다.
3. 파일을 열면 일정한 파일 내용을 읽고 읽으면 파일 내용을stream 조작을 이용하여 서버에 보냅니다.
4. 전송에 성공하면 파일 내용을 다시 읽고 읽기에 성공하면 서버에 보냅니다.
5. 파일 끝까지 읽을 때까지 4단계로 반복합니다.
6. 파일을 닫고 흐름을 닫습니다.
테스트:
1. 서버를 열고 7000 포트를 감청하고 출력을 파일로 바꿉니다.
nc -l 7000 > test_recv.jpg
2. 프로그램을 컴파일하고 실행합니다.
gcc main.c -luv
./a.out test.jpg
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSON
JSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다.
그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다.
저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.
#include
#include
#include
uv_loop_t *loop;
#define DEFAULT_PORT 7000
uv_tcp_t mysocket;
char *path = NULL;
uv_buf_t iov;
char buffer[128];
uv_fs_t read_req;
uv_fs_t open_req;
void on_read(uv_fs_t *req);
void on_write(uv_write_t* req, int status)
{
if (status < 0)
{
fprintf(stderr, "Write error: %s
", uv_strerror(status));
uv_fs_t close_req;
uv_fs_close(uv_default_loop(), &close_req, open_req.result, NULL);
uv_close((uv_handle_t *)&mysocket,NULL);
exit(-1);
}
else
{
uv_fs_read(uv_default_loop(), &read_req, open_req.result, &iov, 1, -1, on_read);
}
}
void on_read(uv_fs_t *req)
{
if (req->result < 0)
{
fprintf(stderr, "Read error: %s
", uv_strerror(req->result));
}
else if (req->result == 0)
{
uv_fs_t close_req;
// synchronous
uv_fs_close(uv_default_loop(), &close_req, open_req.result, NULL);
uv_close((uv_handle_t *)&mysocket,NULL);
}
else
{
iov.len = req->result;
uv_write((uv_write_t *)req,(uv_stream_t *)&mysocket,&iov,1,on_write);
}
}
void on_open(uv_fs_t *req)
{
if (req->result >= 0)
{
iov = uv_buf_init(buffer, sizeof(buffer));
uv_fs_read(uv_default_loop(), &read_req, req->result,&iov, 1, -1, on_read);
}
else
{
fprintf(stderr, "error opening file: %s
", uv_strerror((int)req->result));
uv_close((uv_handle_t *)&mysocket,NULL);
exit(-1);
}
}
void on_connect(uv_connect_t* req, int status)
{
if(status < 0)
{
fprintf(stderr,"Connection error %s
",uv_strerror(status));
return;
}
fprintf(stdout,"Connect ok
");
uv_fs_open(loop,&open_req,path,O_RDONLY,-1,on_open);
}
int main(int argc,char **argv)
{
if(argc < 2)
{
fprintf(stderr,"Invaild argument!
");
exit(1);
}
loop = uv_default_loop();
path = argv[1];
uv_tcp_init(loop,&mysocket);
struct sockaddr_in addr;
uv_connect_t* connect = (uv_connect_t*)malloc(sizeof(uv_connect_t));
uv_ip4_addr("127.0.0.1",DEFAULT_PORT,&addr);
int r = uv_tcp_connect(connect,&mysocket,(const struct sockaddr *)&addr,on_connect);
if(r)
{
fprintf(stderr, "connect error %s
", uv_strerror(r));
return 1;
}
return uv_run(loop,UV_RUN_DEFAULT);
}
1. 서버를 열고 7000 포트를 감청하고 출력을 파일로 바꿉니다.
nc -l 7000 > test_recv.jpg
2. 프로그램을 컴파일하고 실행합니다.
gcc main.c -luv
./a.out test.jpg
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.