本文介绍: 服务端功能描述服务端启动后,等待客户端连接。如果验证通过记录客户端信息。并把该客户端记录信息发送给其他的客户端,也把其他的在线用户发送给用户实现整个网络内的在线客户信息同步服务断开连接删除记录并把结果发送给其他的客户端。与服务端进行连接,连接后把账号信息发送给服务端,服务端验证后,把确认结果通知客户端。如果通过验证客户端从服务端接收其他在线客户端信息并把这些客户信息显示用户。服务端记录每个客户端基本信息:每个客户端的。根据配置文件信息启动服务端程序监听端口等待客户端连接。

Linux系统 + Gcc + Gdb + makefile

实现局域网OICQ程序设计,包括客户端和服务端。

客户描述客户运行开始出现登陆界面。与服务端进行连接,连接后把账号信息发送给服务端,服务端验证后,把确认结果通知客户端。如果通过验证,客户端从服务端接收其他在线客户端信息并把这些客户信息显示用户用户可以选择客户并与之进行信息交流。即发送消息和接受消息。并把结果显示给用户。

服务端功能描述:服务端启动后,等待客户端连接。接受客户端发送过来的账号信息。进行验证。并把验证的结果返回给客户端。如果验证通过,记录客户端的信息。并把该客户端的记录的信息发送给其他的客户端,也把其他的在线用户发送给该用户,实现整个网络内的在线客户信息的同步。接受客户端的断开连接的请求。服务端断开连接,删除记录并把结果发送给其他的客户端。

Sock编程

根据配置文件信息启动服务端程序监听端口等待客户端连接。完成客户端于服务端简单tcp连接。使用I/O复用机制完成客户端与服务端之间的一对多的连接。服务端记录每个客户端的基本信息:每个客户端的IP端口基本信息。使用链表记录保存这些信息。

相关代码参考

客户端:

#include <myhead.h>

typedef struct
{
	char type;
	char name[20];
	char text[128];
}msg_t;
//定义传送消息结构int main(int argc, const char *argv[])
{
	if(argc != 3)
	{
		printf("请输入服务器IP和端口号!n");
		return -1;
	}
//提醒输入IP和端口号
	int cfd = socket(AF_INET,SOCK_DGRAM,0);
	if(cfd == -1)
	{
		perror("socket error");
		return -1;
	}
//创建接字用于通信
	msg_t msg;
	char name[20] = "";
	printf("请输入用户名>>");
	scanf("%s",msg.name);
	getchar();
//输入名字
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(atoi(argv[2]));
	sin.sin_addr.s_addr = inet_addr(argv[1]);
//定义发送的服务器结构char buf[129] = "";
	char rbuf[128] = "";

	bzero(buf,sizeof(buf));
	msg.type = 'L';
	sendto(cfd,&msg,sizeof(msg),0,(struct sockaddr*)&sin,sizeof(sin));
//发送登录信息结构struct pollfd fds[2];
	fds[0].fd = 0;
	fds[0].events = POLLIN;

	fds[1].fd = cfd;
	fds[1].events = POLLIN;
	int res = 0;
//用poll函数多路复用
	while(1)
	{
		res = poll(fds,2,-1);
		if(res == -1)
		{
			perror("poll error");
			return -1;
		}
		else if(res == 0)
		{
			printf("time outn");
			return -1;
		}

		bzero(buf,sizeof(buf));
		bzero(rbuf,sizeof(rbuf));

		if(fds[1].revents == POLLIN)
		{
			recvfrom(cfd,rbuf,sizeof(rbuf),0,NULL,NULL);
			printf("%sn",rbuf);
		}

		if(fds[0].revents == POLLIN)
		{
			fgets(msg.text,sizeof(msg.text),stdin);
			msg.text[strlen(msg.text)-1]='';

			if(strcmp(msg.text,"quit")==0)
			{
				msg.type = 'Q';
				sendto(cfd,&msg,sizeof(msg),0,(struct sockaddr*)&sin,sizeof(sin));
				goto A;
			}
			msg.type = 'C';
			sendto(cfd,&msg,sizeof(msg),0,(struct sockaddr*)&sin,sizeof(sin));
		}
	}
A:
	close(cfd);
	return 0;
}

服务端:

#include <myhead.h>
typedef struct group
{
	char type;
	char name[20];
	char text[128];
}msg_t;
//创建信息结构typedef struct Node
{
	int PORT;
	struct Node* next;
}*Linklist;
//创建链表数据域的结构体
Linklist create_node()
{
	Linklist s=(Linklist)malloc(sizeof(struct Node));
	if(NULL == s)
		return NULL;
	s->PORT =0;
	s->next =NULL;
	return s;
}
//创建链表节点
Linklist insert_rear(Linklist head,int element)
{
	Linklist s=create_node();
	s->PORT=element;

	if(NULL == head)
	{
		head = s;
		return head;
	}
	Linklist p = head;
	while(p->next != NULL)
	{
		p=p->next;
	}
	p->next = s;
	return head;
}
//链表的头删

int lenth(Linklist head)
{
	if(head == NULL)
		return 0;
	int count=0;
	Linklist p=head;
	while(p!=NULL)
	{
		count++;
		p=p->next;
	}
	free(p);
	p=NULL;
	return count;
}
//链表求长度
int find_element(Linklist head,int element)
{
	Linklist p=head;
	for(int i=0;i<lenth(head);i++)
	{
		if(p->PORT == element)
			return i;
		p=p->next;
	}
}
//链表的按照元素查找
Linklist link_del_head(Linklist head)
{
	if(head->next == NULL)
	{
		free(head);head=NULL;
		return head;
	}
	Linklist del=head->next;
	head->PORT=del->PORT;
	head->next=del->next;
	free(del);del=NULL;
	return head;
}
//链表的头删
Linklist link_del_rear(Linklist head)
{
	if(head->next == NULL)
	{
		free(head);
		head = NULL;
		return head;
	}
	Linklist del=head;
	while(del->next->next!=NULL)
	{
		del=del->next;
	}
	free(del->next);
	del->next=NULL;
	return head;
}
//链表的尾删
Linklist link_del_pos(Linklist head,int pos)
{
	if(pos == lenth(head)-1)
	{
		head = link_del_rear(head);
		return head;
	}
	else if(pos == 0)
	{
		head = link_del_head(head);
		return head;
	}
	else
	{
		Linklist p=head;
		for(int i=0;i<pos-1;i++)
		{
			p=p->next;
		}
		Linklist r=p->next;
		p->next=r->next;
		free(r);
		r=NULL;
		return head;
	}
}
//链表的按照信息删除
Linklist del(Linklist head,int element)
{
	if(head ==NULL)
		return head;
	int pos = find_element(head,element);
	head = link_del_pos(head,pos);
	return head;
}
//链表按照位置删除
int main(int argc, const char *argv[])
{
	if(argc != 3)
	{
		printf("请输入服务器IP和端口号!n");
		return -1;
	}

	int sfd = socket(AF_INET,SOCK_DGRAM,0);
	if(sfd == -1)
	{
		perror("socket error");
		return -1;
	}
	//创建套接字用于通信
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(atoi(argv[2]));
	sin.sin_addr.s_addr = inet_addr(argv[1]);
	//定义服务器的信息结构体
	if(bind(sfd,(struct sockaddr*)&amp;sin,sizeof(sin))==-1)
	{
		perror("bind error");
		return -1;
	}
	printf("bind successn");

	struct sockaddr_in cin;
	cin.sin_family = AF_INET;
	socklen_t socklen = sizeof(cin);

	Linklist Usr_PORT=NULL;
	msg_t usr;
	char buf[149] = "";
	char rbuf[130] = "";
	//根据poll函数IO多路复用
	struct pollfd fds[2];
	fds[0].fd = 0;
	fds[0].events = POLLIN;
	fds[1].fd = sfd;
	fds[1].events = POLLIN;
	int res = 0;  //接收select返回值

	while(1)
	{
		res = poll(fds,2,-1);
		if(res == -1)
		{
			perror("poll error");
			return -1;
		}
		else if(res == 0)
		{
			printf("time out");
			return -1;
		}
	
		bzero(buf,sizeof(buf));

		if(fds[0].revents == POLLIN)
		{
			strcpy(buf,"SYSMSG:");
			fgets(buf+7,sizeof(buf)-7,stdin);
			buf[strlen(buf)-1] = '';
			Linklist p = Usr_PORT;
			while(p!= NULL)
			{
				cin.sin_port = htons(p->PORT);
				sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&amp;cin,sizeof(cin));
				p=p->next;
			}
		}

		if(fds[1].revents == POLLIN)
		{
			
			recvfrom(sfd,&amp;usr,sizeof(usr),0,(struct sockaddr*)&amp;cin,&amp;socklen);
			if(usr.type == 'L')
			{
				Usr_PORT = insert_rear(Usr_PORT,ntohs(cin.sin_port));
			
				printf("[%s:%d]已经上线n",usr.name,ntohs(cin.sin_port));
				sprintf(buf,"%s已经上线",usr.name);
				printf("buf = %sn",buf);
				Linklist p = Usr_PORT;
				while(p->next!= NULL)
				{
					cin.sin_port = htons(p->PORT);

					sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&amp;cin,sizeof(cin));
					p=p->next;
				}
			}
			else if(usr.type == 'C')
			{
				sprintf(buf,"%s:%s",usr.name,usr.text);

				Linklist p = Usr_PORT;
				int NONE=ntohs(cin.sin_port);
				while(p!= NULL)
				{
					if(NONE!=p->PORT)
					{
						cin.sin_port = htons(p->PORT);
						sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&(cin),sizeof(cin));
					}
					p=p->next;
				}
			}
			else if(usr.type == 'Q')
			{
				sprintf(buf,"%sdownline",usr.name);
				printf("[%s:%d]downlinen",usr.name,ntohs(cin.sin_port));
				Usr_PORT = del(Usr_PORT,ntohs(cin.sin_port));
				Linklist p = Usr_PORT;
				while(p!= NULL)
				{
					cin.sin_port = htons(p->PORT);
					sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cin,sizeof(cin));
					p=p->next;
				}
			}
		}
	}
	close(sfd);
	return 0;
}

原文地址:https://blog.csdn.net/qq_73902922/article/details/134697567

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_19982.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注