Linux下的飞鸽简要设计框架

以下是我从别的blog上转载的, 关于Linux下的飞鸽简要设计框架, 之所以说是Linux下的, 因为代码是Linux下的. 但是, 设计框架将遵循windows版飞鸽传书的协议和框架.数据包格式:

版本号:包编号:用户名:机器名:命令字:附加信息

  12067943liu d1432hello

以上是一个发送消息的数据包格式,其中32是标示的发消息命令字。附加信息会随着命令字的不同而有所不同,例如,当对方发送了一条消息,你需要返回确认消息时,就需要在附加信息位置加上对方给你发消息时的包编号,只有包编号正确,对方才不会重发。

整个过程都要以以上数据包格式发送数据,因此,将数据包定义为一个结构体

typedef  struct  cmd

{

Unsigned int verision;

Unsigned int packetno;

Char  sendName[];

Char  machineName[];

Unsigned int  fcommandNo;   //命令字

Struct  socketaddr_in   peer;     //这是套接字信息存储结构体

}CMD

为了将实时的在线用户信息返回,就需要建立一个用户链表,

用户信息存储结构体如下:

Typedef  struct  info

{

Int  no;

Char user[];

Char machine[];

Char IP[];

Struct  info  *next;

}INFO;

做完以上工作,接下来将进行总体的架构。因为,总体架构不合格,将会直接影响后面工作的进行。通过二次重写,使我深刻认识到,功能函数的重要性,在一个项目中,有时会对某一功能块进行多次调用,但你又不知道具体使那一块,这是跟着项目进度才可准确知道的。因而,为了方便,就要将一个功能封装成一个功能函数,这即有利于程序的可读性,又使得程序的架构变得容易些。

首先,我们需要知道本地的用户名等信息,这是用来填充CMD结构体中的用户名和机器名信息。这里有用到的两个函数实例

#include<pwd.h>

#include<sys/utsname.h>

Struct  passwd *pwd;

Struct  utsname sysName;

uname(&syaName);

pwd  =  getpwuid(getuid());

通过上面的操作,已经将用户名存入pwd-->pw_name;机器名存入sysName.nodename中。

在进行聊天或者文件传书时,我们需要用到服务器模式,其实udp 服务器模式在一开始就要涉及到,如recvfrom()将作为服务器阻塞,以便等待接收广播后的回送信息,来建立用户列表。所以initSrv ()函数完成tcp udp 服务器的初始化。也就是这里有Udp绑定操作和tcp的绑定,监听操作。

下面将要并行完成命令选择(即ls--列出在线用户,tk--和某人聊天)和消息接收。着里会创建两个线程,一线程(tid1)用来进行命令控制,如,ls--则列举在线用户的所有信息(结构体INFO),具体代码见下边。另一个线程(tid2)则是用recvfrom()阻塞函数来接收网络数据,根据接收到的不同命令字去执行不同的功能函数。例如,命令字为13时,将用户加入信息链表,为2时将用户从链表中删除。等等。。。

本代码只实现了以上的一些功能,即聊天,显示在线用户信息,自动删除下线用户。文件的传送代码没有完成,这里讲述架构思路。

在上面的基础上,我们在主线程中已经创建了两个线程,接着用accept()来阻塞等待某方的tcp连接(connect)。线程tid1中可设置发送文件(主动行为,通过udp发送请求命令字),对方同意接收文件后,就会自动连接(connect())accept(),当有人链接到我的tcp 时,表示要传送文件,这时创建一个线程来接收文来发送文件。当在线程tid2中受到某方的发文件请求,当选择同意后,自动连对方tcp服务器来接收文件。只在传送文件数据时才使用tcp协议。在设计实现中还存在很多细节问题,这个在具体设计中在考虑。

代码:

#ifndef  _MESSAGE_

#define  _MESSAGE_

#include<stdio.h>

#include<stdlib.h>

#include<unistd.h>

#include<sys/socket.h>

#include<netinet/in.h>

#include<arpa/inet.h>

#include<net/if.h>

#include<sys/utsname.h>

#include<string.h>

typedef struct info

{

     int  no;

     char user[20];

     char machine[20];

     char IP[16];

//  struct sockaddr_in newaddr;

     struct info *next;

}INFO;

typedef struct cmd

{

unsigned int version;

unsigned int packetno;

char senderName[30];

char machineName[40];

unsigned int commandNo;

char addtionInfo[500];

struct sockaddr_in peer;

}CMD;

extern int msgsock;

extern int tcpsock;

extern struct passwd* pwd;

extern struct utsname sysName;

extern void initSrv();

extern void initcmd(CMD *cmd,int flag);

extern void sendMsg(CMD *cmd,char *addtionInfo);

extern void strcut(char *ptr[],char *buf);

extern int listUsr(FILE *file);

#endif

//---------------------------------------------------------------------------------

#include"message.h"

#include<string.h>

#include<pthread.h>

#include<sys/types.h>

#include<pwd.h>

static int menno=1;

int msgsock,tcpsock;

struct passwd *pwd;

struct utsname sysName;

struct info *head=NULL,*pf=NULL;

void dlt_user(char *IP);

void add_user(char *username,char *machine,char *IP);

void list_user();

void talk(int no);

void *ctrcmd()

{

CMD cmd;

char info[500];

char fromIP[16]="255.255.255.255";

char buf[40]="";

int no;

initcmd(&cmd,1);

cmd.peer.sin_port=htons(2425);

cmd.peer.sin_family=AF_INET;

inet_pton(AF_INET,fromIP,&cmd.peer.sin_addr.s_addr);

strcpy(info,"liu");

    sendMsg(&cmd,info);

while(1)

{

printf("input:");

fflush(stdout);

//    fgets(buf,40,stdin);

scanf("%s",buf);

//   buf[strlen(buf)-1]='/0';

   if(strcmp(buf,"ls")==0)

  list_user();

   else if(strcmp(buf,"tk")==0)

   {

  //     printf("please choice:");

   //    fflush(stdout);

       scanf("%d",&no);

getchar();

   talk(no);

   //-----------

   }

   else if(strcmp(buf,"exit")==0)

   {

   initcmd(&cmd,2);

  //     inet_pton(AF_INET,fromIP,&cmd.peer.sin_addr.s_addr);

       strcpy(info,"liu");

           sendMsg(&cmd,info);

   exit(0);

   }

}

}

void *process()

{

CMD cmd;

struct sockaddr_in fromaddr;

    int fromlen,fromfd;

int  command; 

char *ptr[10];

char IP[16]="";

char buf[1024];

while(1)

{

          fromlen = sizeof(struct sockaddr);

      if((fromfd = recvfrom(msgsock,buf,1024,0,(struct sockaddr*)&fromaddr,&fromlen))== -1)

      {

     perror("recv error!");

      }

  strcut(ptr,buf);

    inet_ntop(AF_INET,&fromaddr.sin_addr.s_addr,IP,16);

   printf("IP:%s/n",IP);

command =atoi( ptr[4])&0x000000ff;

printf("command:%d/n",command);

   if(command==1||command== 3)

{

add_user(ptr[2],ptr[3],IP);

}

else if(command==2 )

{

dlt_user(IP);

}

else if(command == 32)

{

printf("%s:%s/n",ptr[2],ptr[5]);

initcmd(&cmd,33);

cmd.peer.sin_port = fromaddr.sin_port;

inet_pton(AF_INET,IP,&cmd.peer.sin_addr.s_addr);

sprintf(buf,"%s",ptr[1]);

sendMsg(&cmd,buf);

}

}

pthread_exit(NULL);

}

void talk(int no)

{

CMD cmd;

struct info *temp;

char buf[100]="";

int flag=0;

if(head == NULL)

{

printf("no one online!/n");

return ;

}

temp = head;

while(temp != NULL)

{

if(temp->no==no)

{

flag = 1;

   cmd.peer.sin_port=htons(2425);

   cmd.peer.sin_family=AF_INET;

   inet_pton(AF_INET,temp->IP,&cmd.peer.sin_addr.s_addr);

   break;

}

else

temp = temp->next;

}

if(flag==0)

{

printf("no that element!/n");

return;

}

while(1)

{

    printf("MSG:");

memset(buf,0,sizeof(buf));

   fgets(buf,100,stdin);

   buf[strlen(buf)-1]='/0';

   if(strcmp(buf,"quit")==0)

   {

   initcmd(&cmd,33);

       sendMsg(&cmd,buf);

   break;

   }

   initcmd(&cmd,32);

   sendMsg(&cmd,buf);

}

}

void sendMsg(CMD *cmd,char *addtionInfo)

{

char buf[600];

if(addtionInfo == NULL)

    strcpy(cmd->addtionInfo,"");

else

    strcpy(cmd->addtionInfo,addtionInfo);

sprintf(buf,"%d:%d:%s:%s:%d:%s",cmd->version,cmd->packetno,cmd->senderName,cmd->machineName,cmd->commandNo,cmd->addtionInfo);

        if( sendto(msgsock,buf,strlen(buf),0,(struct sockaddr*)&cmd->peer,sizeof(cmd->peer)) == -1)

        {

        perror("send error!");

        }

return ;

}

void strcut(char *ptr[],char *buf)

{

char *token=NULL;

char *str=":";

int i=0;

if(buf==NULL)

return ;

token = strtok(buf,str);

ptr[0]=token;

while(token != NULL)

{

ptr[i++]=token;

token = strtok(NULL,str);

}

return;

}

void add_user(char *username,char *machine,char *IP)

{

struct info *pb,*tmphead;

tmphead = head;

printf("start here!/n");

while(tmphead != NULL)

{

if(strcmp(tmphead->IP,IP)==0)

{

printf("if here!/n");

return ;

}

else

tmphead = tmphead->next;

}

printf("malloc here!/n");

pb = (struct info*)malloc(sizeof(struct info));

pb->no=menno++;

    strcpy(pb->user,username);

strcpy(pb->machine,machine);

strcpy(pb->IP,IP);

     if(head==NULL)

 {

printf("add head here!/n");

 head=pf=pb;

 pb->next = NULL;

 }

 else

 {

printf("addr pf here!/n");

 pf->next = pb;

 pb->next = NULL;

 pf = pb;

 }

}

void list_user()

{

struct info *tmp;

if(head==NULL)

return ;

tmp = head;

while(tmp!=NULL)

{

printf("NO:%d   ",tmp->no);

printf("USER:%s  ",tmp->user);

printf("MACH:%s  ",tmp->machine);

printf("IP:%s/n",tmp->IP);

tmp = tmp->next;

}

}

void dlt_user(char *IP)

{

struct info *temp,*tphead;

// int flag=0;

if(head==NULL)

return;

temp=tphead=head;

while(tphead != NULL )

{

if(strcmp(tphead->IP,IP)==0)

break;

    temp=tphead;

tphead=tphead->next;

}

if(tphead == NULL)

return ;

if(head==tphead && tphead->next==NULL)

{

head=NULL;

menno--;

free(tphead);

}

else if(head == tphead && tphead->next!=NULL)

{

head = tphead->next;

temp =tphead->next;

while(temp !=NULL)

{

temp->no--;

temp=temp->next;

}

menno--;

free(tphead);

}

else if(head != tphead && tphead->next != NULL)

{

temp->next = tphead->next;

temp=tphead->next;

while(temp !=NULL)

{

temp->no--;

temp=temp->next;

}

menno--;

free(tphead);

}

else

{

pf=temp->next = NULL;

menno--;

free(tphead);

}

}

void initcmd(CMD *cmd,int flag)

{

if(cmd == NULL)

   return;

bzero(cmd,sizeof(cmd));

cmd->version=1;

cmd->packetno=(unsigned int)time(NULL);

strcpy(cmd->senderName,pwd->pw_name);

strcpy(cmd->machineName,sysName.nodename);

cmd->commandNo = flag;

return;

}

void initSrv()

{

struct sockaddr_in server;

int broadcast_en = 1;

msgsock = socket(AF_INET,SOCK_DGRAM,0);

tcpsock = socket(AF_INET,SOCK_STREAM,0);

server.sin_family = AF_INET;

server.sin_port = htons(2425);

server.sin_addr.s_addr = htonl(INADDR_ANY);

   if( setsockopt(msgsock,SOL_SOCKET,SO_BROADCAST,&broadcast_en,sizeof(broadcast_en))==-1)

   {

   printf("broadcast setsockopt error!/n");

   exit(1);

   }

   if(bind(msgsock,(struct sockaddr*)&server,sizeof(struct sockaddr))!=0)

   {

   perror("udp bind error!");

   exit(1);

   }

   if(setsockopt(tcpsock,SOL_SOCKET,SO_REUSEADDR,&broadcast_en,sizeof(broadcast_en))==-1)

   {

   printf("tcp setsock error!/n");

   exit(1);

   }

   if(bind(tcpsock,(struct sockaddr*)&server,sizeof(struct sockaddr))!=0)

   {

   perror("tcp bind error!");

   exit(1);

   }

   if(listen(tcpsock,10)!=0)

   {

   perror("listen error!");

   exit(1);

   }

}

int main()

{

     pthread_t tid1,tid2;

 uname(&sysName);

 pwd = getpwuid(getuid());

 initSrv(); 

    if(pthread_create(&tid1,NULL,(void *)*ctrcmd,NULL)!=0)

 {

 perror("pthread creat error!");

 exit(1);

 }

     if(pthread_create(&tid2,NULL,(void *)*process,NULL)!=0)

 {

 perror("pthread creat error!");

 exit(1);

 }

 while(1)

 {

          

 }

return 0;

}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值