====== تابع ()recv ======
از این تابع برای خواندن از یک سوکت از نوع stream استفاده می شود.
#include
#include
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
مقدار بازگشتی این تابع برابر است با تعداد بایتی که خوانده و در buf ذخیره شده است.
مثال برای ارسال و دریافت یک پیغام از سمت سرور با کلاینت telnet
#include
#include
#include
#include
#include
#include
#include
#include
#define PORT "3435"
#define BACKLOG 120
#define BUFSIZE 1000
int main()
{
int status, sockopt;
fprintf(stdout, "Configuring local address ...\n");
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_STREAM;
struct addrinfo *bind_address, *rp;
status = getaddrinfo(NULL, PORT, &hints, &bind_address);
if (status != 0) {
fprintf(stderr, "getaddrinfo() error: %s\n", gai_strerror(status));
exit(EXIT_FAILURE);
}
int listen_socket;
for (rp = bind_address; rp != NULL; rp = rp->ai_next) {
fprintf(stdout, "Creating socket ...\n");
listen_socket = socket(rp->ai_family, rp->ai_socktype,
rp->ai_protocol);
if (listen_socket == -1) {
perror("socket() error ");
continue;
}
sockopt = 1;
status = setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR,
(void*)&sockopt, sizeof(sockopt));
if (status == -1) {
perror("setsockopt() SO_REUSEADDR error ");
exit(EXIT_FAILURE);
}
sockopt = 0;
status = setsockopt(listen_socket, IPPROTO_IPV6, IPV6_V6ONLY,
(void*)&sockopt, sizeof(sockopt));
if (status == -1) {
perror("setsockopt() IPV6_V6ONLY error ");
exit(EXIT_FAILURE);
}
fprintf(stdout, "Binding socket to local address ...\n");
status = bind(listen_socket, rp->ai_addr, rp->ai_addrlen);
if (status == -1) {
perror("bind() error ");
continue;
}
break;
}
freeaddrinfo(bind_address);
if (rp == NULL) {
fprintf(stderr, "Failed to bind()\n");
exit(EXIT_FAILURE);
}
fprintf(stdout, "Listening ...\n");
status = listen(listen_socket, BACKLOG);
if (status == -1) {
perror("listen() error ");
exit(EXIT_FAILURE);
}
fprintf(stdout, "Waiting for connections ...\n");
fflush(stdout);
int client_socket;
struct sockaddr_storage client_addr;
socklen_t client_addrlen = sizeof(client_addr);
client_socket = accept(listen_socket, (struct sockaddr *)&client_addr,
&client_addrlen);
if (client_socket == -1) {
perror("accept() error ");
exit(EXIT_FAILURE);
}
char *ipver, ipstr[INET6_ADDRSTRLEN];
void *addr;
if (client_addr.ss_family == AF_INET) {
ipver = "IPv4";
addr = &(((struct sockaddr_in *)&client_addr)->sin_addr);
} else if (client_addr.ss_family == AF_INET6) {
ipver = "IPv6";
addr = &(((struct sockaddr_in6 *)&client_addr)->sin6_addr);
} else {
ipver = "Unknown";
}
inet_ntop(client_addr.ss_family, addr, ipstr, sizeof(ipstr));
printf("Client is connected from %s address %s\n", ipver, ipstr);
printf("Reading client request ...\n");
ssize_t readlen;
char readbuf[BUFSIZE];
readlen = recv(client_socket, readbuf, BUFSIZE, 0);
if (readlen < 1) {
fprintf(stderr, "Error Reading client request\n");
if(readlen == -1)
perror("recv() error ");
exit(EXIT_FAILURE);
}
// null terminating client message
if(readlen > 0 && readlen < BUFSIZE)
readbuf[readlen] = 0;
else
readbuf[0] = 0;
fprintf(stdout, "Cleint message:\n---\n%s\n---\n", readbuf);
fprintf(stdout, "Sending message to cleint...\n");
char *msg = "Hello world\n";
status = send(client_socket, msg, strlen(msg), 0);
if (status == -1)
perror("send() error ");
else
fprintf(stdout, "Byte sent = %d\n", status);
printf("Closing connection...\n");
close(client_socket);
printf("Closing listening socket...\n");
close(listen_socket);
printf("Finished.\n");
return 0;
}
کلاینت
$ telnet 127.0.0.1 3435
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
this is a test message
Hello world
Connection closed by foreign host.
خروجی سرور
Configuring local address ...
Creating socket ...
Binding socket to local address ...
Listening ...
Waiting for connections ...
Client is connected from IPv6 address ::ffff:127.0.0.1
Reading client request ...
Cleint message:
---
this is a test message
---
Sending message to cleint...
Byte sent = 12
Closing connection...
Closing listening socket...
Finished.
کلاینت جایگزین telnet در مثال بالا
#include
#include
#include
#include
#include
#include
#include
#define PORT "3435"
#define SERVER "127.0.0.1"
#define BUFSIZE 250
int main()
{
char *msg = "This is a test message.";
int status, sockfd;
printf("Configuring local address ...\n");
struct addrinfo hints, *res, *rp;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
status = getaddrinfo(SERVER, PORT, &hints, &res);
if (status != 0) {
fprintf(stderr, "getaddrinfo() error: %s\n", gai_strerror(status));
exit(EXIT_FAILURE);
}
for (rp = res; rp != NULL; rp = rp->ai_next) {
printf("Creating socket ...\n");
sockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (sockfd == -1) {
perror("socket() error ");
continue;
}
printf("Connecting to server ...\n");
status = connect(sockfd, rp->ai_addr, rp->ai_addrlen);
if (status == -1) {
perror("connect() error ");
close(sockfd);
continue;
}
break;
}
freeaddrinfo(res);
if (rp == NULL) {
fprintf(stderr, "Could not connect() \n");
exit(EXIT_FAILURE);
}
printf("Sending message to server ...\n");
status = send(sockfd, msg, strlen(msg), 0);
if (status == -1)
perror("send() error ");
else
printf("Byte sent = %d\n", status);
printf("Reading server message ...\n");
char buf[BUFSIZE];
status = recv(sockfd, buf, BUFSIZE, 0);
if (status < 1) {
fprintf(stderr, "Error reading client message.\n");
if (status == -1)
perror("recv() error ");
}
// null terminating client message
if (status > 0 && status < BUFSIZE)
buf[status] = 0;
else
buf[0] = 0;
if (strlen(buf) > 0)
printf("Client message:\n---\n%s\n---\n");
printf("Closing connection ...\n");
close(sockfd);
printf("Finished.\n");
return 0;
}
خروجی کلاینت
Configuring local address ...
Creating socket ...
Connecting to server ...
Sending message to server ...
Byte sent = 23
Reading server message ...
Client message:
---
Hello world
---
Closing connection ...
Finished.
خروجی سرور
Configuring local address ...
Creating socket ...
Binding socket to local address ...
Listening ...
Waiting for connections ...
Client is connected from IPv6 address ::ffff:127.0.0.1
Reading client request ...
Cleint message:
---
This is a test message.
---
Sending message to cleint...
Byte sent = 12
Closing connection...
Closing listening socket...
Finished.