linux socket网络 绑定失败 bind errorInvalid argument

自我进阶2.0 2018-10-15 08:57:22
 
#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();
}




麻烦大佬们帮我看看
...全文
2237 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
cs十七 2019-01-06
  • 打赏
  • 举报
回复
另外,代码中,是不是有点问题? 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);
        }
    }
}
cs十七 2019-01-06
  • 打赏
  • 举报
回复
楼上已经回答了,想来赚点积分。 对于调用socket API返回值的判断,可以看看《UNP》书中的包裹函数,你已经使用了 SA 宏,应该能够看到的。 既然你在程序中每次调用API都考虑进行检查返回结果,那可以这样:
#include <stdlib.h> //exit, EXIT_FAILURE

if(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);
}
張公㜽 2018-12-17
  • 打赏
  • 举报
回复
==-1,写成了bind的参数了,所以很多说上建议用 == 时,将常量写在前面,变量写在后面,如if(1 == a)...
Shunhwa 2018-12-12
  • 打赏
  • 举报
回复
bind那行,==-1写到)外面一点

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧