Linux下的socket编程(2)

使用socket实现点对点聊天功能

p2p服务器端:

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

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

#define PORT 8080
#define  ERR_EXIT(m)\
		do \
		{\
			perror(m); \
			exit(EXIT_FAILURE); \
		} while(0)
void handler(int pid)
{
	exit(EXIT_SUCCESS);
}
int main(void)
{
	int listenfd;
	if((listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) //create a new socket
	/*if((listenfd = socket(AF_INET, SOCKET_STREAM, 0)) < 0)*/
		ERR_EXIT("socket");

	struct sockaddr_in servaddr;
	memset(&servaddr, 0, sizeof(servaddr));         //initial the struct of sockaddr(IP address and port)
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(PORT);
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	/*servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");*/
	/*inet_aton("127.0.0.1", &servaddr.sin_addr);*/
	
	int on = 1;                                                               
	if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)//use REUSEADDR to use port at immediate
		ERR_EXIT("setsockopt");
	
	if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) //bind the socket
		ERR_EXIT("bind"); 
	
	if(listen(listenfd, SOMAXCONN) < 0) //listen the client socket
		ERR_EXIT("listen");

	struct sockaddr_in perraddr; //initial the listen socket
	socklen_t peerlen = sizeof(perraddr);
	int conn;
	
	pid_t pid;//use to fork the new process

	if((conn = accept(listenfd, (struct sockaddr*)&perraddr, &peerlen)) < 0)
		ERR_EXIT("accept");
	printf("ip=%s port=%d\n", inet_ntoa(perraddr.sin_addr), ntohs(perraddr.sin_port));
	pid = fork();
	if(pid == -1)
		ERR_EXIT("fork");
	if(pid == 0)
	{	
		signal(SIGUSR1, handler);
		close(listenfd);
		char sendbuff[1024] = {0};
		while(fgets(sendbuff, sizeof(sendbuff), stdin) != NULL)
		{
			write(conn, sendbuff, strlen(sendbuff));
			memset(sendbuff, 0, sizeof(sendbuff));
		}
		close(conn);
		printf("child close\n");
	}
	else
	{
		char recvbuff[1024];
		while(1)
		{
			memset(recvbuff, 0, sizeof(recvbuff));
			int ret = read(conn, recvbuff, sizeof(recvbuff));
			if(ret == 0)
			{
				printf("client_close\n");
				break;
			}
			else if(ret == -1)
				ERR_EXIT("read");
			fputs(recvbuff, stdout);
		}
		kill(pid, SIGUSR1);
		close(conn);
		printf("parent close\n");
		exit(EXIT_SUCCESS);
	}

	return 0;	
}

p2p客户端:
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

#define  ERR_EXIT(m)\
		do \
		{\
			perror(m); \
			exit(EXIT_FAILURE); \
		} while(0)
void handler(int pid)
{
	printf("pid = %d\n", pid);
	exit(EXIT_SUCCESS);
}

int main(void)
{
	int sock;
	if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
	/*if((listenfd = socket(AF_INET, SOCKET_STREAM, 0)) < 0)*/
		ERR_EXIT("socket");
	struct sockaddr_in servaddr;
	memset(&servaddr, 0, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(8080);
	servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
	
	if(connect(sock, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
		ERR_EXIT("connect");
	char recvbuff[1024],sendbuff[1024];
	pid_t pid;
	pid = fork();
	if(pid == -1)
		ERR_EXIT("fork error");
	else if(pid == 0)
	{
		while(1)
		{
			memset(recvbuff, 0, sizeof(recvbuff));
			int ret = read(sock, recvbuff, sizeof(recvbuff));
			if(ret == -1)
				ERR_EXIT("read error");
			else if(ret == 0)
			{
				printf("service close\n");
				break;
			}
			fputs(recvbuff, stdout);
		}
		close(sock);
		printf("child colse\n");
		kill(pid, SIGUSR1);
		exit(EXIT_SUCCESS);
	}
	else
	{
		signal(SIGUSR1, handler);
		memset(sendbuff, 0, sizeof(sendbuff));
		while(fgets(sendbuff, sizeof(sendbuff), stdin) != NULL)
		{
			write(sock, sendbuff, strlen(sendbuff));
			memset(&sendbuff, 0, sizeof(sendbuff));
		}
		close(sock);
		printf("parent close\n");
		exit(EXIT_SUCCESS);
	}
	return 0;	
}


;