实现聊天室的功能 :C/C++ socket通信,一个服务端,多个客户端,客户端之间可以群聊

这是我第一次尝试性的发篇博客,记述我用C/C++ 在Linux环境下socket网络通信,客户端和服务端通信使用包头,包体来解决粘包。以下是我的一些见解,和客户端和服务端的代码。希望可以帮助到同在学习的大家。

首先C/C++ 不是跨平台的,因此在window环境和Linux环境使用的函数是不一样的,我使用的是Linux平台的。

  1. Linux环境的函数比window好用,方便.
  2. C/C++的socket一般用在 Linux环境下的服务端,用户客户端用C/C+应该比较少,用java ,c#跨平台的比较多

虽然用的是Linux环境,但我们不用专门下个虚拟机装Linux,win10 可以开启Linux子系统

大家手动换台 :        https://jingyan.baidu.com/article/624e74596633a034e8ba5a2b.html

现在展示下程序的效果

 

除此之外我还加了管理员,不过功能还只能看 消息记录

 

服务端的代码如下:

 

#include
#include
using namespace std;
#include
#include 
#include
#include
#include
#include
#include
#include
#include
#define BUFMAX 1024
#define FILENAME "share.txt"

struct packet
{
	int len;
	char name[16];		//4+16->20
	char buf[BUFMAX];
};

void func(int flag)
{
	cout<<"write进程退出"<0)
		{
			if( (nread=read(fd,bufp,nleft))<=0 )
			{
					cout<<"连接中断"<0)
                {
                        nwrite=write(fd,bufp,nleft);
                        nleft-=nwrite;
                        bufp+=nwrite;
                }
                return count;
        }


void root_usr(int connectfd)  // root 用户
{
	int ret,len;
	packet pack;
	memset(pack.name,0,16);
	while(1)
	{
	strcpy(pack.buf,
	"**********欢迎 Root 管理员**********\n\n1 . 查看聊天记录\n 2 . 删除聊天记录\n 乱按 -》 退出  \n");
	len=strlen(pack.buf)+1;
	pack.len=htonl(len);
	writen(connectfd,&pack,len+20);
		ret=read(connectfd,&pack,4);
		if(ret<=0)
		return;
		len=ntohl(pack.len);
		ret=read(connectfd,&pack.name,len+16);
		if(ret<=0)
		return;
        if( strlen(pack.buf)!=1 )
		{cout<0)  //父进程 接受数据
			{
				pack=(struct packet *)shmat(shmid,  (void*)0, 0);
			    if(pack==(void *)-1)
				      cout<<"shmat失败"<len);
					num=readn(connectfd,pack->name,nlen+16);
                                        test(pid,num);

					cout<name<<" : "<buf<name)!=0 )
						{
							 if(  strcmp(name_tmp,pack->name)||strcmp(buf_tmp,pack->buf) ) 
							  {
									break;
						          }
						}
					}
					strcpy(name_tmp,pack->name);
					strcpy(buf_tmp,pack->buf) ;
					nlen=strlen(pack->buf)+1;	//  有'\0'
					int zz=write(connectfd,pack,nlen+20);
					if(zz<=0)
					cout<<"************write 失败 ***"<1)	//父进程 继续监听
			close(connectfd);
		else
		{
			cout<<"1pid错误"<

 

服务端代码如下:

#include
using namespace std;
#include 
#include 
#include
#include
#include
#include
#include
#include
#define BUFMAX 1024

struct packet
{
	int len;
	char name[16];
	char buf[BUFMAX];
};

void test(pid_t pid,int num)
{
	if(num<=0)
     {
          if(num==0)
            {
                 cout<<"连接中断  read进程关闭"<0)
		{
			if( (nread=read(fd,bufp,nleft))<=0 )
			{
				cout<<"*****nead"<0)
                {
                        if( (nwrite=write(fd,bufp,nleft))<=0 )
                        {
                              cout<<"连接中断"<>pack.name;


	pid=fork();
	if(pid>0)
	{
		while(1)
		{
			num=readn(connectfd,&pack,4);
			test(pid,num);
			nlen=ntohl(pack.len);
			num=readn(connectfd,pack.name,nlen+16);
			test(pid,num);

			cout<>pack.buf; 
			nlen=strlen(pack.buf)+1;	//  '\0'
			pack.len=htonl(nlen);
			write(connectfd,&pack,nlen+20);
			//memset(pack.buf,0,nlen);
		}
	}
	else
	cout<<"pid错误"<

 

如果大家觉得在本机上面测试无聊的话,可以在阿里云买一个Linux服务器,有学生证的话很便宜,把服务端程序放

上去,客户端代码的IP地址改成阿里云分配的公网IP,还有服务端和客户端的端口号改成阿里云允许的端口。这样你电脑

的客户端程序就可以跟别人的电脑的客户端通信了,就跟微信群聊 “差不多” 了。 如果觉得客户端太丑了,可以用其他

语言写一个界面,现在我就是和同学一起弄了,我专门服务端 ,同学则用C#重新写一份带图像界面的客户端   

你可能感兴趣的:(c++)