Ubuntu上进行socket编程,多用户连接  _Android, Python及开发编程讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  Android, Python及开发编程讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 2363 | 回复: 0   主题: Ubuntu上进行socket编程,多用户连接          下一篇 
    本主题由 koei123 于 2015-6-1 14:53:27 移动
d87025284
注册用户
等级:新兵
经验:62
发帖:59
精华:0
注册:2011-10-31
状态:离线
发送短消息息给d87025284 加好友    发送短消息息给d87025284 发消息
发表于: IP:您无权察看 2015-5-5 16:47:25 | [全部帖] [楼主帖] 楼主

代码如下

服务器端代码:

#include <stdio.h>
#include <stdlib.h>
#include <i386-linux-gnu/sys/types.h>
#include <i386-linux-gnu/sys/stat.h>
#include <netinet/in.h>
#include <i386-linux-gnu/sys/socket.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <i386-linux-gnu/sys/ipc.h>
#include <errno.h>
#include <i386-linux-gnu/sys/shm.h>
#include <time.h>
#include <arpa/inet.h>
#define PERM S_IRUSR|S_IWUSR
#define MYPORT 5500 //宏定义,定义通信端口
#define BACKLOG 10 //宏定义,定义服务程序可以连接的最大客户数量
#define WELCOME "|---------Welcome to the chat room!----------|" //宏定义,当客户端连接到服务器时,向客户发送此欢迎字符
//转换函数,将int类型转换成char*类型
void itoa(int i,char*string)
{
      int power,j;
      j=i;
      for(power=1;j>=10;j/=10)
      power*=10;
      for(;power>0;power/=10)
      {
            *string++='0'+i/power;
            i%=power;
      }
      *string='\0';
}
//得到当前系统的时间
void get_cur_time(char *time_str)
{
      time_t timep;
      struct tm *p_curtime;
      char *time_tmp;
      time_tmp = (char*)malloc(2);
      memset(time_tmp,0,2);
      memset(time_str,0,20);
      time(&timep);
      p_curtime = localtime(&timep);
      strcat(time_str,"(");
      itoa(p_curtime->tm_hour,time_tmp);
      strcat(time_str,time_tmp);
      strcat(time_str,":");
      itoa(p_curtime->tm_min,time_tmp);
      strcat(time_str,time_tmp);
      strcat(time_str,":");
      itoa(p_curtime->tm_sec,time_tmp);
      strcat(time_str,time_tmp);
      strcat(time_str,")");
      free(time_tmp);
}
//创建共享存储区
key_t shm_create()
{
      key_t shmid;
      if((shmid = shmget(IPC_PRIVATE,1024,PERM)) == -1)
      {
            fprintf(stderr,"Create Share Memory Error:%s\n\a",strerror(errno));
            exit(1);
      }
      return shmid;
}
//端口绑定函数,创建套件字,并绑定到指定端口
int bindPort(unsigned short int port)
{
      int sockfd;
      struct sockaddr_in my_addr;
      sockfd = socket(AF_INET,SOCK_STREAM,0);//创建基于六套接字
      my_addr.sin_family = AF_INET; //IPv4协议族
      my_addr.sin_port = htons(port);//端口转换
      my_addr.sin_addr.s_addr = INADDR_ANY;
      bzero(&(my_addr.sin_zero),0);
      if(bind(sockfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr)) == -1)
      {
            perror("bind");
            exit(1);
      }
      printf("bind success!\n");
      return sockfd;
}
void write_in_file(char* buf_in)
{
      FILE *fp;
      if((fp = fopen("/home/wbb/workspace/1.txt","a+")) == NULL)
      {
            printf("文件不能打开!\n");
            exit(1);
      }
      fprintf(fp,"%s\n",buf_in);
      fclose(fp);
}
int main(int argc,char *argv[])
{
      socklen_t sockfd,clientfd,recvbytes;//定义监听套接字、客户套接字
      socklen_t sin_size;
      pid_t pid,ppid; //定义父子线程标记变量 pid_t == Process ID_Type 宏定义insigned int 类型
      char *buf,*r_addr,*w_addr,*temp,*time_str; //定义临时存储区
      struct sockaddr_in their_addr; //定义地址结构
      key_t shmid;
      shmid = shm_create(); //创建共享存储区
      temp = (char*)malloc(255);
      time_str = (char*)malloc(20);
      sockfd = bindPort(MYPORT); //绑定端口
      while(1)
      {
            if(listen(sockfd,BACKLOG) == -1) //指定端口上监听
            {
                  perror("listen");
                  exit(1);
            }
            printf("listening......\n");
            if((clientfd = accept(sockfd,(struct sockaddr*)&their_addr,&sin_size)) == -1)
            {
                  perror("accept");
                  exit(1);
            }
            printf("accept from: %s\n",inet_ntoa(their_addr.sin_addr));
            send(clientfd,WELCOME,strlen(WELCOME),0);//发送问候消息
            buf = (char*)malloc(255);
            ppid = fork();//创建子进程
            if(ppid == 0)
            {
                  pid = fork(); //创建子进程
                  while(1)
                  {
                        if(pid >0)
                        {
                              //父进程用于接收信息
                              memset(buf,0,255);
                              if((recvbytes = recv(clientfd,buf,255,0))<=0)
                              {
                                    perror("recv1");
                                    close(clientfd);
                                    raise(SIGKILL);
                                    exit(1);
                              }
                              //write buf's data to share memory
                              w_addr = shmat(shmid,0,0);
                              memset(w_addr,'\0',1024);
                              strncpy(w_addr,buf,1024);
                              get_cur_time(time_str);
                              strcat(buf,time_str);
                              printf("接收的:%s\n",buf);
                              write_in_file(buf);
                        }
                        else if(pid == 0)
                        {
                              //子进程用于发送信息
                              //scanf("%s",buf);
                              sleep(1);
                              r_addr = shmat(shmid,0,0);
                              if(strcmp(temp,r_addr)!=0)
                              {
                                    strcpy(temp,r_addr);
                                    get_cur_time(time_str);
                                    strcat(r_addr,time_str);
                                    if(send(clientfd,r_addr,strlen(r_addr),0) == -1)
                                    {
                                          perror("send");
                                    }
                                    memset(r_addr,'\0',1024);
                                    strcpy(r_addr,temp);
                              }
                        }
                        else
                        perror("fork");
                  }
            }
      }
      printf("------------------------\n");
      free(buf);
      close(sockfd);
      close(clientfd);
      return 0;
}


客户端代码:

#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <i386-linux-gnu/sys/socket.h>
#include <i386-linux-gnu/sys/types.h>
#include <string.h>
#include <netdb.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
int main(int argc,char *argv[]) {
      struct sockaddr_in clientaddr; // 定义地址结构
      pid_t pid;
      int clientfd,sendbytes;//定义客户端套接字
      struct hostent *host;
      char *buf,*buf_r;
      if(argc < 4) //输入字符串个数
      {
            printf("usage:\n");
            printf("%s host port name\n",argv[0]);
            exit(1);
      }
      host = gethostbyname(argv[1]);
      if((clientfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
      {
            perror("socket\n");
            exit(1);
      }
      //绑定客户端套接字
      clientaddr.sin_family = AF_INET;
      clientaddr.sin_port = htons((uint16_t)atoi(argv[2]));
      clientaddr.sin_addr = *((struct in_addr*)host->h_addr);
      bzero(&(clientaddr.sin_zero),0);
      if(connect(clientfd,(struct sockaddr*)&clientaddr,sizeof(struct sockaddr)) == -1)
      {
            //连接服务器
            perror("connect\n");
            exit(1);
      }
      buf = (char*)malloc(120);
      memset(buf,0,120);
      buf_r = (char*)malloc(100);
      if(recv(clientfd,buf,100,0) == -1)
      {
            perror("recv");
            exit(1);
      }
      printf("\nP:%s\n",buf);
      pid = fork(); // 创建子进程
      while(1)
      {
            if(pid>0)
            {
                  //父进程用于发送消息
                  //get_cur_time(time_str);
                  strcpy(buf,argv[3]);
                  strcat(buf,":");
                  memset(buf_r,0,100);
                  fgets(buf_r,100,stdin);
                  strncat(buf,buf_r,strlen(buf_r)-1);
                  if((sendbytes = send(clientfd,buf,strlen(buf),0)) == -1)
                  {
                        perror("send\n");
                        exit(1);
                  }
            }
            else if(pid == 0)
            {
                  //子进程用于接收消息
                  memset(buf,0,100);
                  if(recv(clientfd,buf,100,0)<=0)
                  {
                        perror("recv:");
                        close(clientfd);
                        raise(SIGSTOP);
                        exit(1);
                  }
                  printf("%s\n",buf);
            }
            else
            perror("fork");
      }
      close(clientfd);
      free(buf_r);
      free(buf);
      buf = NULL;
      buf_r = NULL;
      return 0;
}


实现结果:

1.服务器端:

2.客户端1:

3.客户端2:

4.实现样式:

5.存储内容:



--转自 北京联动北方科技有限公司

该贴由koei123转至本版2015-6-1 14:53:27



赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论