#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();
}
麻烦大佬们帮我看看
解决方案 »
- 求助
- 如何在CmakeLists.txt中实现LOCAL_CFLAGS := -fvisibility=hidden隐藏符号表的作用
- linux内核空间kthread_run创建的线程怎样设置优先级呢
- 环境"Windows10安装Ubuntu16.04双系统"
- 超级萌新,求助VMware安装Ubuntu显示operating system not found
- 内核跑不起来。老是Starting kernel ... data abort
- 安装LInix Red hat 时,无法进入系统,出现一大串英文,
- u-boot中用usb命令检测不到U盘,可能是什么原因?
- linux内存一直被占用,手动释放不成功,找不到占用内存相应的进程
- 为啥我反向解析错误,
- linux platform bus一个driver多个device的问题
- win10引导被覆盖
对于调用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);
}
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);
}
}
}