1. 程式人生 > >csapp書上socket的伺服器和客戶端的程式碼

csapp書上socket的伺服器和客戶端的程式碼

客戶端的程式碼: 

#include "csapp.h"


int main(int argc, char **argv) 
{
	int clientfd, port;
	char *host, buf[MAXLINE];
	rio_t rio;
	
	if (argc != 3)
		{
			fprintf(stderr, "usage: %s <host> <port>\n", argv[0]);
			exit(0);
		}
		
		host = argv[1];
		port = atoi(argv[2]);
		printf("----000\n");
		clientfd = Open_clientfd(host, port);
		printf("----1111\n");
		Rio_readinitb(&rio, clientfd);
		
		while (Fgets(buf, MAXLINE, stdin) != NULL)
		{
			Rio_writen(clientfd, buf, strlen(buf));
		printf("---test---\n");
			Rio_readlineb(&rio, buf, MAXLINE);
			Fputs(buf, stdout);
		}
	  Close(clientfd);
	  exit(0);
}

伺服器的程式碼:

#include "csapp.h"


void echo(int connfd)
{
	size_t n;
	char buf[MAXLINE];
	rio_t rio;
	
	Rio_readinitb(&rio, connfd);
	while ((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0)
	{
		printf("server received %lu by66tes \n", n);
		printf("%s\n", buf);
	//	Rio_writen(connfd, buf, n);
	}
}

int main(int argc, char **argv)
{
	int listenfd, connfd, port, clientlen;
	
	struct sockaddr_in clientaddr;
	struct hostent *hp;
	char *haddrp;
	
	if (argc != 2)
		{
			fprintf(stderr, "usage: %s <port> \n", argv[0]);
			exit(0);
		}
		
		port = atoi(argv[1]);
		listenfd = Open_listenfd(port);
		while (1)
		{
			clientlen = sizeof(clientaddr);
			connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen);
			
			/* determine the domin name and IP address of the client. */
			hp = Gethostbyaddr((const char *)&clientaddr.sin_addr.s_addr, sizeof(clientaddr.sin_addr.s_addr), AF_INET);
			haddrp = inet_ntoa(clientaddr.sin_addr);
			printf("server connect to %s (%s)\n", hp->h_name, haddrp);
			echo(connfd);
			Close(connfd);
			
		}
		exit(0);
		
	
}

    也可以用select 來實現這個伺服器程式碼.

#include "csapp.h"
void echo(int connfd);
void command(void);

int main(int argc, char **argv)
{
	int listenfd, connfd, port;
	socklen_t clientlen = sizeof(struct sockaddr_in);
	struct sockaddr_in clientaddr;
	fd_set read_set, ready_set;
	
	if (argc != 2)
		{
			fprintf(stderr, "usage: %s <port>\n", argv[0]);
			exit(0);
		}
		
		port = atoi(argv[1]);
		listenfd  = Open_listenfd(port);
		
		FD_ZERO(&read_set);                    /* clear read set. */
		FD_SET(STDIN_FILENO, &read_set);       /* add stdin to read set. */
		FD_SET(listenfd, &read_set);           /* add listenfd to read set. */
		//printf("hhhhhhhhhhhhhhhhhhhhhhh\n");
		while (1)
		{
	ready_set = read_set;
		//	printf("---------------------: %d\n", listenfd + 1);
			Select(listenfd + 1, &ready_set, NULL, NULL, NULL);
		//	printf("11111111111111111111111111\n");
			if (FD_ISSET(STDIN_FILENO, &ready_set))
				{
					command();                 /* read command line from stdin. */
				}
		//	printf("------------------------\n");
			if (FD_ISSET(listenfd, &ready_set))
				{
					connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen);
					echo(connfd);             /* echo client input until EOF. */
					Close(connfd);
				}
		}
}


void command(void)
{
	char buf[MAXLINE];
	if (!Fgets(buf, MAXLINE, stdin))
		exit(0);   /* EOF */
		
	printf("%s\n", buf);    /* Process the input command. */
}

void echo(int connfd)
{
	size_t n;
	char buf[MAXLINE];
	rio_t rio;
	
	Rio_readinitb(&rio, connfd);
	while ((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0)
	{
		printf("server received %lu by66tes \n", n);
		//printf("%s\n", buf);
		Rio_writen(connfd, buf, n);
	}
}


  這是書上的原始碼,很容易看明白, 這樣就可以大概瞭解socket的基本方法。以下 執行

       ./echoserver 8080&

       ./echoclient ubuntu-64bit-compile 8080 

     這樣就可以啦。