본문 바로가기

공부/LinuxServer

6. 정보를 주고 받기 - send(), recv()

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);
}