| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 540 人关注过本帖
标题:模拟聊天室程序//带注释求修改
只看楼主 加入收藏
David_o
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2012-2-23
结帖率:50%
收藏
已结贴  问题点数:10 回复次数:1 
模拟聊天室程序//带注释求修改
程序代码:
//服务器程序
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>
#include <time.h>
#include <semaphore.h>

int fds[100];//保存所有的客户端的socket描述符,最大100
int size=0;
void sendtoall(const char* msg)//向所有人发送信息函数
{
        int i;
        for(i=0; i<size; i++)
                  {
           send(fds[i], msg, strlen(msg), 0);
                   }
}
void* task(void* p)//子进程函数
{
        int sd = *(int*)p;
        char buf[100] = {};
        while(1)
                  {
                sem_wait(&lock);//加锁有问题行吗???????
                memset(buf, 0, sizeof(buf));
                recv(sd, buf, sizeof(buf), 0);
                sendtoall(buf);//发送给所有在fds数组内的客户端
                sem_post(&lock);
                  }
}  

int main()
{
        sem_t lock;
        sem_init(&lock,0,1);//初始化锁变量
        int sockfd = socket(PF_INET, SOCK_STREAM, 0);//获取sockfd,
        if(sockfd==-1)perror("创建socket失败"),exit(-1);
      
   struct sockaddr_in addr;//建立网络信息
        addr.sin_family = PF_INET;
        addr.sin_port = htons(8888);
        addr.sin_addr.s_addr = inet_addr("192.168.180.53");
      
   int res = bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));//绑定
        if(res==-1)perror("绑定失败"),exit(-1);
        printf("绑定成功\n");
      
   listen(sockfd, 10);//监听

        struct sockaddr_in fromaddr={};
        socklen_t len;
        int sd,sd_temp;//每次while(1)循环,sd的值,会不断改变,故保存在sd_temp变量中
        while(1)
               {
                sd = accept(sockfd, (struct sockaddr*)&fromaddr,&len);//与客户端建立联系
                if(sd==-1)
               {
                        perror("等待客户端连接失败");
                        continue;
                }
                fds[size++] = sd;//客户端socket ++
      
            pthread_t tid;//建立子进程
                sd_temp = sd;
                pthread_create(&tid, 0, task, &ssd);
               }
     sem_destroy(&lock);
}//客户端代码
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>

void* task(void* p)//子进程函数
{
        int sd = *(int*)p;
        char buf[100] = {};
        while(1)//如何改写代码,自己输入的消息,不会被收到?????
       {
                memset(buf, 0, sizeof(buf));
                recv(sd, buf, sizeof(buf), 0);
                printf("%s\n", buf);
        }
}

int main()
{
       
        int sockfd = socket(PF_INET, SOCK_STREAM, 0);//创建socket
        if(sockfd==-1)perror("创建socket失败"),exit(-1);
       
        struct sockaddr_in addr;//建立通信地址
        addr.sin_family = PF_INET;
        addr.sin_port = htons(8888);
        addr.sin_addr.s_addr = inet_addr("192.168.180.53");
       
        int res = connect(sockfd, (struct sockaddr*)&addr, sizeof(addr));//连接服务器
        if(res==-1)perror("连接失败"),exit(-1);
        printf("连接成功\n");

        pthread_t tid;//建立子进程
        pthread_create(&tid, 0, task, &sockfd);
       
   printf("请输入你的姓名:");//本机参与聊天代码
        char name[20] = {};
        scanf("%s", name);
        while(1)///客户端代码,用while循环,服务器程序会退出,客服端死循环??????
        {
                scanf("%*c");
           char buf[100] = {};
                printf("输入内容:");
                scanf("%s", buf);
                char msg[120] = {};
                strcpy(msg, name);
                strcat(msg, ":");
                strcat(msg, buf);
                send(sockfd, msg, strlen(msg), 0);//发送信息       
        }
}
搜索更多相关主题的帖子: include 聊天室 发送信息 void 
2012-02-25 11:10
草狼
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:2
帖 子:577
专家分:1040
注 册:2010-4-6
收藏
得分:10 
1: lock 应该定义成全局变量
2: sd_temp 个人感觉没用
3: pthread_create(&tid, 0, task, &ssd); 这ssd应该是sd把 打错了吧
4: 还有客户端关闭后在别的客户端输入可能会导致服务端关闭的可能原因是
当你把客户端关闭后 fds数组中并没有改变 从而导致了sendtoall向无链接的套接字发信息而出错
5: 这样改下就可以让自己收不到自己输入的内容
void sendtoall(const char* msg, int sock)//向所有人发送信息函数
{
    int i;
    for(i=0; i<size; i++)
    {
        if(fds[i] != sock)
            send(fds[i], msg, strlen(msg), 0);
    }
}
6: recv是阻塞的 所以被发送给别的客户端的信息只有第一个客户端的是能执行的 别的都是无效的
应为当你第一个客户端的线程被recv阻塞时  sem_post()就无法解锁, 所以客户端发送的信息都在服务端的task函数中的
sem_wait(&lock)这里被阻塞而无法之星sendtoall函数

上面的都是个人看法,对错页不一定,,我也是刚在学网络编程 呵呵
2012-02-25 18:40
快速回复:模拟聊天室程序//带注释求修改
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.014924 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved