您的位置:首页 > 理论基础 > 计算机网络

TCP echo demo

2015-08-10 16:05 465 查看
[netcomm.h]

#ifndef NETCOMM_H
#define NETCOMM_H

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>

#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#define MAXLINE 1000
#define LISTENQN 6
#define SERPORT 2400

static void str_echo(int connfd);

/*
* Read n bytes from a descriptor
*/
ssize_t
readn(int fd, void *vptr, size_t n)
{
size_t nread;
size_t nleft;
char *ptr;

nread = 0;
nleft = n;
ptr = vptr;

while (nleft > 0)
{
if ( (nread = read(fd, ptr, nleft)) < 0)
{
if (errno == EINTR) /* Read again */
nread = 0;
else
return -1;
}
else if (nread == 0) /* EOF */
break;

nleft -= nread;
ptr += nread;
}

return (n - nleft);
}

/*
* Write n bytes into a descriptor
*/
ssize_t
writen(int fd, void *vptr, size_t n)
{
size_t nleft;
size_t nwriten;
void *ptr;

nleft = n;
nwriten = 0;
ptr = vptr;

while (nleft > 0)
{
if ( (nwriten = write(fd, ptr, nleft)) <= 0)
{
if (nwriten < 0 && errno == EINTR)
nwriten = 0;
else
return (-1);
}

nleft -= nwriten;
ptr += nwriten;
}

return (n);
}

/*
* Read a line from descriptor
*/
ssize_t
readline(int fd, void *vptr, size_t maxlen)
{
int n, rc;
char *ptr;
char c;

ptr = vptr;

for (n = 1; n <= maxlen; ++n)
{
again:
if ( (rc = read(fd, &c, 1)) == 1)
{
*ptr++ = c;
if (c == '\n')
break;
} else if (rc == 0) /* EOF */
{
*ptr = 0;
return (n - 1);
} else
{
if (errno == EINTR)
goto again;
return (-1);
}
}

*ptr = 0;
return n;
}
#endif

[echo_server.c]

/*
* Echo server demo
*/
#include "netcomm.h"

int
main(int argc, char **argv)
{
int listenfd, clifd;
struct sockaddr_in cliaddr, serveraddr;
pid_t pid;
socklen_t cliaddrlen;

/* Initialize server addr */
if ( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
printf("Create socket error!\n");
exit(-1);
}

bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(SERPORT);

/* Bind server addr to listen fd */
if (bind(listenfd, &serveraddr, sizeof(serveraddr)) < 0){
printf("bind addr error!\n");
exit(-1);
}

if (listen(listenfd, LISTENQN) < 0) {
printf("Listen error!\n");
exit(-1);
}

for (; ;) {
cliaddrlen = sizeof (cliaddr);
if ( (clifd = accept(listenfd, &cliaddr, &cliaddrlen)) < 0) {
if (errno == EINTR)
continue;
else
exit(-1);
} else {
if ( (pid = fork()) == 0) {
close(listenfd);
str_echo(clifd);
exit(0);
}
}
close(clifd);
}

waitpid(pid, NULL, 0);
}

static void
str_echo(int connfd) {
size_t n;
char buf[MAXLINE];

again:
while ( (n = read(connfd, buf, sizeof(buf))) > 0) {
if (writen(connfd, buf, n) < 0) {
printf("Write connfd error!\n");
exit(-1);
}
}

if ( n < 0 && errno == EINTR)
goto again;
else if ( n < 0)
exit(-1);

exit(0);
}

[echo_client.c]

/*
* Echo client demo
*/
#include "netcomm.h"

static void str_client(FILE *fp, int connfd);

int
main(int argc, char **argv)
{
int clifd;
struct sockaddr_in serveraddr;

if (argc != 2) {
printf("Usage:echo_client <IP>\n");
exit(-1);
}

/* Initialize client fd */
if ( (clifd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
printf("Create socket error!\n");
exit(-1);
}

bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
if (inet_pton(AF_INET, argv[1], &serveraddr.sin_addr) < 0) {
printf("inet_pton error!\n");
exit(-1);
}
serveraddr.sin_port = htons(SERPORT);

if (connect(clifd, &serveraddr, sizeof(serveraddr)) < 0) {
printf("connect error!\n");
exit(-1);
}

str_client(stdin, clifd);

exit(0);
}

static void
str_client(FILE *fp, int connfd) {
char send[MAXLINE], receive[MAXLINE];

while ( fgets(send, MAXLINE, fp) != NULL) {
if (writen(connfd, send, sizeof(send)) < 0) {
printf("writen error!\n");
exit(-1);
}

if (readline(connfd, receive, MAXLINE) == 0) {
printf("str_client: server terminated.\n");
return;
}

fputs(receive, stdout);
}

exit(0);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: