linux c/c++ 聊天小程序代码示例 (使用socket 和 IO 多路复用技术)


声明:在linux 下的ubuntu 下编译运行以下代码分为客服端和服务器段代码,可直接运行使用


客户端
1 头文件 common.h 

#ifndef _CHAT_
#define _CHAT_

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netdb.h>
#include <sys/select.h>




#endif

2  实现 client.c

#include "common.h"


int creat_tcp_client(const char *ip, int port)
{
	int sk1;
	struct sockaddr_in service_addr;
	struct hostent *tmp;
	int ret;

	sk1=socket(AF_INET, SOCK_STREAM, 0);
	if(-1 == sk1)
	{
		perror("scorkt");
		exit(-1);
	}

	memset(&service_addr, 0, sizeof(service_addr));
	service_addr.sin_family=AF_INET;
	service_addr.sin_port= htons(port);
	tmp=gethostbyname(ip);
//	printf("%d" ,tmp);
	if(NULL == tmp)
	{
		perror("gethostbyname");
		exit(-1);
	}

	memcpy(&service_addr.sin_addr, (struct in_addr *)tmp->h_addr, 4);
	
	//getchar();

	ret=connect(sk1,(struct sockaddr *)&service_addr, sizeof(service_addr));
	if(-1 == ret)
	{
		perror("connect");
		exit(-1);
	}

	listen(sk1, 5);
	printf("connect success \n");

	return sk1;
	
}


	/*  ******* MAIN************    */

	

int main(int argc, char *argv[])
{

	int newfd;
	int ret;
	int maxfd;
	fd_set fs;
	struct timeval tv;
	int i;
	char buf[1024];
	int len;
	int len1;
	int port;
	
	
	

	if(argc < 3)
	{
		fprintf(stderr, "Usage  ip  port ...\n ");
		exit (-1);
	}
	printf("**********\n");
	port = atoi(argv[2]);
	
	newfd=creat_tcp_client(argv[1], port);
	printf("%d",newfd);

	while(1)
	{
		FD_ZERO(&fs);
		FD_SET(0, &fs);
		maxfd=newfd+1;
		tv.tv_sec=2;
		tv.tv_usec=0;

		ret=select(maxfd, &fs, NULL, NULL,&tv);
		if(-1 == ret)
		{
			perror("select");
			exit(-1);
		}
		for(i=0; i<maxfd; i++)
		{
			if(FD_ISSET(i,&fs))
			{
				fgets(buf, sizeof(buf), stdin);
				len=strlen(buf);
				buf[len-1]=0;
				if(strncmp(buf, "quit", 4) == 0)
				{
					printf("client readdly quit !\n");
					close(newfd);
				}
				
				write(newfd, buf, sizeof(buf));
			}
			else if(i == newfd)
			{
				len1=read(newfd, buf, sizeof(buf));
				if(len1 == 0)
				{
					printf("connect close!!\n");
					close(newfd);
					exit(-1);	
				}
				
				buf[len1]=0;
				printf("recv is %s", buf);
			}
			
		}
		
	}

	

}



服务端

1 头文件 common_clist.h

#ifndef _CLIST_
#define _CLIST_

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

#define HEAD    0
#define TAIL   -1

#define DATA    0
#define OFFSET -1

#define UP      0
#define DOWN   -1

#define U       0
#define N      -1


typedef struct usr{
	char name;
	int fd;
}data_t;

typedef struct node1{
	data_t data;
	struct node *next;
}NODE;

NODE *creat_clist_node1(data_t data);
void insert_clist_node1(NODE *head, data_t data, int offset);
void delet_clist_node1(NODE *head, char data, int flage);
NODE *find_clist_node1(NODE *head, char data);
void show_clist(NODE *head);

#endif


头文件 common_chat.h
#ifndef _CHAT_
#define _CHAT_

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netdb.h>
#include <sys/select.h>




#endif

实现头文件 clist.c

#include "common_clist.h"

NODE *creat_clist_node1(data_t data)
{
	NODE *node1= (NODE *)malloc(sizeof(NODE));
	if(NULL == node1)
		exit(-1);
	
	node1->data = data;
	node1->next = NULL;

	return node1;
}

void insert_clist_node1(NODE *head, data_t data, int offset)
{
	NODE *node1 = creat_clist_node1(data);
	switch(offset)
	{
	case HEAD:
		node1->next = head->next;
		head->next = node1;
		break;
	case TAIL:
		while(head->next != NULL)
			head = head->next;
		head->next = node1;
		break;
	default:
		if(0 > offset)
			insert_clist_node(head, data, HEAD);
		else
		{
			while(offset--)
			{
				if(head->next == NULL)
					break;
				head = head->next;
			}
			insert_clist_node(head, data, HEAD);
		}	
		break;
	}
}

void delet_clist_node1(NODE *head, char data, int flage)
{
	NODE *t;
	switch(flage)
	{
	case DATA:
		while(head->next != NULL)
		{
			if(head->next->data.name == data)
			{
				t = head->next;
				head->next = t->next;
				free(t);
				break;
			}
			head = head->next;
		}
		break;
	default:
		break;
	}
}

NODE *find_clist_node1(NODE *head, char data)
{
	while(head->next!= NULL)
	{
		if(head->next->data.name== data)
			return head->next;
		head = head->next;
	}
	return NULL;
}

void show_clist(NODE *head)
{
	while(head->next != NULL)
	{
		printf("%c ", head->next->data.name);
		head = head->next;
	}
	printf("\n");
}




实现头文件 sevice.c

#include "common_clist.h"
#include "common_chat.h"
//#include "clist.c"


int creat_service_port(port)
{
	int sk;
	struct sockaddr_in self;
	int bid;
	
	 
	sk=socket(AF_INET, SOCK_STREAM, 0);
	if(-1 == sk)
	{
		perror("socket");
		exit(-1);
	}
	memset(&self, 0, sizeof(self));

	self.sin_family=AF_INET;
	self.sin_port=htons(port);
	self.sin_addr.s_addr=0;
	
	bid=bind(sk, (struct sockaddr *)&self,sizeof(self))	;
	if(-1 == bid)
	{
		perror("bind");
		exit(-1);
	}

	listen(sk, 5 );
	printf("service aleady listen.... \n");
		
	return sk;

}



/*       MAIN      */



int main(int argc, char *argv)
{

		int port;
		int listenfd;
		int maxfd;
		struct timeval tv;
		int retval;
		int newfd;
		int ret;
		int i;
		int confd;
		char buf[1024];
		int byte;
		fd_set rfds,jtbf;

		
	/*open service port */
	if(argc != 2)
	{
		fprintf(stderr, "Usage service port");
		exit(-1);
	}

	port=atoi("argv[1]");
	listenfd=creat_service_port(port);

	printf("service creat clist...\n");
	NODE*creat_clist_node1(port);
	//printf("%s,",node1.data.data);

	printf("service will be accent ...\n");
	
	FD_ZERO(&rfds);
	FD_SET(listenfd, &rfds);
	tv.tv_sec=2;
	tv.tv_usec=0;
	
	maxfd=listenfd+1;

	while(1)
	{
		/* 监听备份*/

		jtbf=rfds;
		tv.tv_sec=2;
		tv.tv_usec=0;
		
		
		
		ret=select(maxfd, &rfds, NULL, NULL, &tv);
		if(-1 == ret)
		{
			perror("slect");
			exit(-1);
		}
	/* resive will be  resive client connect !! */
		
		else
		{
			for(i=0; i<=maxfd; i++)
			{
				if(FD_ISSET(i, &jtbf));
				{
					if(i == listenfd)
					{
						confd=accept(listenfd, NULL, NULL);
						
						FD_SET(confd, &rfds);
						maxfd=maxfd > confd ? maxfd:confd;
					}

		/* service resive client message and send message */
					else
					{
						if(byte=read(confd, buf, sizeof(buf))<=0)
						{
							close(confd);
							FD_CLR(i,&rfds);
						}
						else
						{
							write(i,buf, sizeof(buf));	
						}
						
					}
					
				}
			}
		}
		
	}

	
	
	
}



  • 我喜欢程序员,他们单纯、固执、容易体会到成就感;面对压力,能够挑灯夜战不眠不休;面对困难,能够迎难而上挑战自我。他 们也会感到困惑与傍徨,但每个程序员的心中都有一个比尔盖茨或是乔布斯的梦想“用智慧开创属于自己的事业”。我想说的是,其 实我是一个程序员


syw_selfimpr新浪微博地址: http://weibo.com/u/2945271402

 如果觉得本文对您有帮助,请点击‘顶’支持一下,您的支持是我写作最大的动力,谢谢。


  • 7
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值