#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <pthread.h>short PORT = 9000;int sockfd;     //服务器socket
int fds[10];    //客户端socketfd
int size = 10;  //连接数
typedef struct sockaddr SA;void init()
{
sockfd = socket(AF_INET,SOCK_STREAM,0);  //创建套接字
if(sockfd == -1)
{
perror("create socket fail!");
exit(-1);
} struct sockaddr_in addr;
bzero(&addr, sizeof(struct sockaddr_in));  //结构体清零
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockfd, (SA *)&addr, sizeof(addr) == -1)) //绑定
{
perror("bind fail!");
exit(-1);
}
if(listen(sockfd,10) == -1)        //监听套接字
{
perror("listen fail!");
exit(-1);
}
}void SendMeg(char *msg)     //转发信息
{
int i;
for(i = 0;i<size;i++)
{
if(fds[i] != 0)
{
printf("sendto%d\n",fds[i]);
send(fds[i],msg,strlen(msg),0);
}
}
}void* service_t(void *p)
{
int fd = *(int*)p;
printf("pthread = %d",fd);
while(1)
{
char buf[128] = {};
if(recv(fd,buf,sizeof(buf),0) <= 0)
{
int i;
for(i = 0; i < size;i++)
{
if(fd == fds[i])
{
fds[i] = 0;
break;
}
}
printf("num:%d退出!\n",fd);
pthread_exit(&i);
}
SendMeg(buf);
}
}void service()
{
printf("=====Server Start!=====\n");
while(1)
{
struct sockaddr_in fromaddr;
socklen_t len = sizeof(fromaddr);
int fd = accept(sockfd,(SA*)&fromaddr,&len);
if(fd == -1)
{
printf("客户端连接错误!\n");
continue;
}
int i =0;
for(i = 0; i<size;i++)
{
if(fds[i] == 0)
{
fds[i] == fd;
printf("fd = %d\n",fd);
pthread_t tid;
pthread_create(&tid,0,service_t,&fd);
break;
}
if(size == i)
{
char *str = "满员";
send(fd,str,strlen(str),0);
close(fd);
}
}
}
}int main()
{
init();
service();
}
麻烦大佬们帮我看看

解决方案 »

  1.   

    bind那行,==-1写到)外面一点
      

  2.   

    ==-1,写成了bind的参数了,所以很多说上建议用 == 时,将常量写在前面,变量写在后面,如if(1 == a)...
      

  3.   

    楼上已经回答了,想来赚点积分。
    对于调用socket API返回值的判断,可以看看《UNP》书中的包裹函数,你已经使用了 SA 宏,应该能够看到的。
    既然你在程序中每次调用API都考虑进行检查返回结果,那可以这样:
    #include <stdlib.h> //exit, EXIT_FAILUREif(sockfd < 0)
    {
    perror("create socket fail!");
    exit(EXIT_FAILURE);
    }
    if(bind(sockfd, (SA *)&addr, sizeof(addr)) < 0) //绑定
    {
    perror("bind fail!");
    exit(EXIT_FAILURE);
    }if(listen(sockfd,10) < 0) //监听套接字
    {
    perror("listen fail!");
    exit(EXIT_FAILURE);
    }对accept函数的判断,《unp》中是这样子 <errno.h>中有这两个错误码的定义
    int
    Accept(int fd, struct sockaddr *sa, socklen_t *salenptr)
    {
    int n;again:
    if ( (n = accept(fd, sa, salenptr)) < 0) {
    #ifdef EPROTO
    if (errno == EPROTO || errno == ECONNABORTED)
    #else
    if (errno == ECONNABORTED)
    #endif
    goto again;
    else
    err_sys("accept error");
    }
    return(n);
    }
      

  4.   

    另外,代码中,是不是有点问题?
    void* service_t(void *p)是每个 连接一个线程,那它内部调用的 void SendMeg(char *msg) 函数,我想应该是要发送给当前的这个连接吧?那是不是应该把当前的这个连接套接字传递给 void SendMeg(char *msg) 呢?
    void* service_t(void *p)
    {
        int fd = *(int*)p;
        //printf("pthread = %d",fd);
    printf("current thread id=[%ld]\n", pthread_self());
        while(1)
        {
            char buf[128] = {};
            if(recv(fd,buf,sizeof(buf),0) <= 0)
            {
                int i;
                for(i = 0; i < size;i++)
                {
                    if(fd == fds[i])
                    {
                        fds[i] = 0;
                        break;
                    }
                }
                printf("num:%d退出!\n",fd);
                pthread_exit(&i);
            }
            SendMeg(buf, fd);
        }
    }void SendMeg(char *msg, int connfd)     //转发信息
    {
        int idx;
        for(idx=0; idx<size; idx++)
        {
            if(fds[idx] == connfd)
            {
                printf("send to %d\n",fds[idx]);
                send(fds[idx], msg, strlen(msg),0);
            }
        }
    }