1. header
#include <sys/types.h>
#include <sys/socket.h>
2. function
int send(int socket, const void *msg, size_t len, int flags);
int recv(int socket, void *buf, size_t len, int flags);
1) int socket: 통신의 주체가 되는 소켓 디스크립터
send - 정보를 받을 소켓 디스크립터 주소
recv - 정보를 보내는 소켓 디스크립터 주소
2) const void *msg : 상대에게 보낼 자료의 포인터
3) void *buf : 받은 메세지를 저장할 버퍼 포인터
4) size_t len : 전송되는 메세지의 크기 (byte 단위)
5) int flags : 플레그(옵션)
flags | 설명 |
MSG_DONTWAIT |
전송 전에 대기 상태가 필요하다면 기다리지 않고 -1을 반환하면서 복귀 수신을 위해 대기가 필요하다면 기다리지 않고 -1을 반환하면서 바로 복귀 |
MSG_NOSIGNAL | 상대방과 연결이 끊겼을 때 , SIGPIPE 시그널을 받지 않도록 합니다. |
4) return :
성공 |
실패 |
실제 전송(수신)한 바이트 수 |
-1 |
3. 사용
1. Server
//pingpong server
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#define SA struct sockaddr_in
int main()
{
const int port = 80;
int sock = socket(AF_INET, SOCK_STREAM, 0);
int conn;
SA addr, clientAddr;
socklen_t len = sizeof(clientAddr);
char buffer[2048];
int send_len;
int recv_len;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sock, (struct sockaddr*)&addr, sizeof(SA)) == -1) {
fprintf(stderr, "Bind Error : %s\n", strerror(errno));
close(sock);
return(-1);
}
else printf("connected\n");
if (listen(sock, 5) == -1) {
printf("listen fail\n");
}
while (1) {
conn = accept(sock, (struct sockaddr*)&clientAddr, &len);
while (recv_len = recv(conn, buffer, 256, 0) == -1) {
if (errno == EINTR) {
continue;
}
else {
fprintf(stderr, "Recv Error : %s\n", strerror(errno));
return -1;
}
}
while (send_len = send(conn, buffer, 256, 0) == -1) {
if (errno == EINTR) {
continue;
}
else {
fprintf(stderr, "Send Error : %s\n", strerror(errno));
return -1;
}
}
close(conn);
}
}
2. Client
//pingpong client
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#define SA struct sockaddr_in
int main()
{
const int port = 80;
int sock = socket(AF_INET, SOCK_STREAM, 0);
SA addr;
char buffer[2048];
int recv_len;
int send_len;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr("255.255.255.0");
if (connect(sock, (struct sockaddr*)&addr, sizeof(SA)) == -1) {
fprintf(stderr, "Connect Error : %s\n", strerror(errno));
return(-1);
}
else printf("connected\n");
//Make send message
for (int i = 0; i < 50;) {
for (int j = 0; j < 5; j++, i++)
buffer[i] = 'a' + j;
}
printf("%s\n", buffer);
while (send_len = send(sock, buffer, 256, 0) == -1) {
if (errno == EINTR) {
continue;
}
else {
fprintf(stderr, "Send Error : %s\n", strerror(errno));
return -1;
}
}
while (recv_len = recv(sock, buffer, 256, 0) == -1) {
if (errno == EINTR) {
continue;
}
else {
fprintf(stderr, "Recv Error : %s\n", strerror(errno));
return -1;
}
}
printf("%s\n", buffer);
}
'공부 > LinuxServer' 카테고리의 다른 글
[Linux Server] Node.js로 TCP 에코 서버 구현하기 (+ 방화벽 설정, 포트 열기) (0) | 2020.09.14 |
---|---|
5. 클라이언트의 접속 요청을 허락하고 통신용 소켓 생성 - accept() (2) | 2019.06.10 |
4. 클라이언트에서 서버에 연결 요청하기 - connect() (0) | 2019.06.06 |
3. 클라이언트의 접속요청 확인하기 - listen() (0) | 2019.05.30 |
2. 소켓에 정보 지정하기 - bind() (0) | 2019.04.26 |