2013年9月3日星期二

bind () function appears Address already in use error! ! !

Tragedy, and out of this error, but also in the setsockopt () function after use (set over SOCK_REUSEADDR) in the case, do not know how to solve, have encountered similar problems do, google for a long time, also mentioned that problem is not resolved, alas, the multiplayer chat program Dounong a day, which has resolved to tell the younger, very grateful! ! !
------ Solution ---------------------------------------- ----
not ah! If you set the SOCK_REUSEADDR, this error does not occur ah! Because the address is already reused, "Address already in use" it does not matter. Your source code stickers out? Will it be another question
------ Solution --------------------------------- -----------
see if you are using port status, is not LISTEN state?

Even if you set that option, LISTEN state for the port, but also can not be repeated listens
------ Solution ------------------ --------------------------


the same way, the general has spent the port can not be bind again, unless considered port reuse some of the programs
------ Solution ------------ --------------------------------
another try
------ For reference port only ---------------------------------------
I posted about the source code, which I see online a chat program, he said above, is to support people chatting, using the select () function, the listener:
comments in the code are some of my questions, please enlighten heroes! ! (I was in a loom, start the server, and client segments)

client qq_client.c

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/un.h>

char buffer[256];
void * pthread_function(void * arg);
const int portbase = 1785;           //服务器和客户端设置了同样的端口号
int main()
{
int result;
int client_socketfd;
char * local = "127.0.0.1";   //(1)网上说同一台机子,既当客户端,又当服务器端,就设置这个ip,也不知道为什么??

fd_set read_set;
int max_fd;

struct sockaddr_in client_address;        //connect()用的地址信息
client_address.sin_family = AF_LOCAL;
client_address.sin_addr.s_addr = inet_addr(local);
client_address.sin_port = htons((unsigned short)portbase);
client_socketfd = socket(AF_LOCAL,SOCK_STREAM,0);

printf("client socket id is %d\n",client_socketfd); //这里可以看到client_socketfd的值为3
if(client_socketfd <0)
{
printf("socket error\n");
exit(0);
}
if(connect(client_socketfd,(struct sockaddr*)&client_address,sizeof(client_address))!= 0)
{
perror("can't connect the server\n");
exit(0);
}
max_fd = client_socketfd+1;

while(1)
{
FD_ZERO(&read_set);
FD_SET(0,&read_set);
FD_SET(client_socketfd,&read_set);

result = select(max_fd,&read_set,(fd_set*)NULL,(fd_set*)NULL,(struct timeval*)NULL);     //用select()实现对socket,和键盘输入的监听
if(result<1)
{
printf("select\n");
exit(0);
}
else
{
if(FD_ISSET(0,&read_set))
{

memset(buffer,'\0',sizeof(buffer));
fgets(buffer,sizeof(buffer),stdin);
if(strncmp("quit",buffer,4) == 0)
{
printf("you quit the chat\n");
break;
}
else
{
if(write(client_socketfd,buffer,sizeof(buffer)) == -1)
{
printf("write error\n");
exit(0);
}

}
}
if(FD_ISSET(client_socketfd,&read_set))
{

memset(buffer,'\0',sizeof(buffer));
result = read(client_socketfd,buffer,sizeof(buffer));
if(result == -1)
{
printf("read error\n");
exit(0);
}
if(result == 0)
{
printf("server terminate\n");
break;
}
else
{
printf("server:%s",buffer);
}

}
}
}
close(client_socketfd);
exit(0);
}



qq_server.c server which uses a thread function pthread_function (), to handle accept () function to monitor links

#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
#include <memory.h>
#include <unistd.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <netdb.h>
#include <pthread.h>
#include <netinet/in.h>

char buffer[256];
pthread_mutex_t work_lock;    //用到了互斥锁,对buffer【】这个读写区的资源管理
void * pthread_function(void * arg);
extern int errno;
const int portbase = 1785;   //端口号和客户端一样
int main()
{
int opt = 1;        //用于setsockopt(),不过没用,还是Address already in use ,只好改个端口号,很麻烦!
socklen_t len;
int result;
char * local ="127.0.0.1";
socklen_t length;

struct sockaddr_in server_address,client_address;
int server_socketfd,client_socketfd;
int client_length;
pthread_t a_thread;
printf("server has start\n");
memset(&server_address,0,sizeof(server_address));
server_address.sin_family = AF_LOCAL;
server_address.sin_port = htons((unsigned short) portbase);
server_address.sin_addr.s_addr = inet_addr(local); //(2)这样使用可以吗???

server_socketfd = socket(AF_LOCAL,SOCK_STREAM,0);
if(server_socketfd < 0)
{
printf("can't get a server socket\n");
exit(0);
}
len = sizeof(opt);
setsockopt(server_socketfd,SOL_SOCKET,SO_REUSEADDR,(char*)&opt,len); //这里设置了端口可复用

result = bind(server_socketfd,(struct sockaddr*)&server_address,sizeof(server_address));
if(result<0)
{
perror("can't bind the server socket to network\n");
exit(0);
}
result = pthread_mutex_init(&work_lock,NULL); //初始化锁

if(result<0)
{
printf("can't   initialize th mutex\n");
exit(0);
}
result = listen(server_socketfd,5);     //可处理5个链接请求
client_length = (int)sizeof(client_address);
printf("进入无线循环\n");
        while(1)
{
result = accept(server_socketfd,(struct sockaddr*)&client_address,&client_length);   //accetp()获得链接请求,然后让线程处理

if(result<0)
{
printf("can't bind the server socket to network\n");
exit(0);
}
result = pthread_create(&a_thread,NULL,pthread_function,(void *)client_socketfd);
//(3)这里我真郁闷了,在客户端qq_client.c中,我查看了那个client_socketfd的值为3,但是传到线程函数中,这个值(本来我是 让 fd = (int)clien_socketfd; 发现fd的值是个很大的值,晕死!!???,怎么会这样???
if(result < 0)
{
printf("can't create the thread\n");
exit(0);
}

}
}

void * pthread_function(void * arg)   //线程函数
{
int fd =  3;    //我直接 fd  = 3了,那个值,真不知道怎么来的,其实这样也就无法多人聊天,但是这一对一,也有问题,唉!!!
int max_fd;
int result;
fd_set read_set;

printf("chat begin\n");
while(1)
{
FD_ZERO(&read_set);
FD_SET(0,&read_set);
FD_SET(fd,&read_set);

max_fd = fd+1;
pthread_mutex_lock(&work_lock);

result = select(max_fd,&read_set,(fd_set*)NULL,(fd_set*)NULL,(struct timeval*)NULL);

if(result < 1)
{
printf("select");
}

if(FD_ISSET(0,&read_set))   //服务器端有键盘输入
                {
printf("服务器端有输入#\n");
                        memset(buffer,'\0',sizeof(buffer));
                        fgets(buffer,sizeof(buffer),stdin);
                        if(strncmp("quit",buffer,4) == 0)   //如果输入的是quit,聊天结束,解锁
                        {
                                printf("server has terminate thr chat\n");
                                pthread_mutex_unlock(&work_lock);
                                break;
                        }
                        else
                        {
                                result = write(fd,buffer,sizeof(buffer));
                                if(result<0)
                                {
                                        perror("write error:");
                                        exit(0);
                                }

                        }
                }

if(FD_ISSET(fd,&read_set))       //客户端通过socket有信息到达服务器端
{
printf("客户端的信息到达\n");
memset(buffer,'\0',sizeof(buffer));
result = read(fd,buffer,sizeof(buffer));
if(result < 0)
{
printf("can't read from the client socket\n");
exit(0);
}
if(result==0)
{
printf("the client has terminate the chat\n");
pthread_mutex_unlock(&work_lock);
break;
}
else
{
printf("client:%s\n",buffer);
}
}
pthread_mutex_unlock(&work_lock);
sleep(1);                //防止单个线程一直占用buffer【】读写区,而不能实现多人聊天
}
close(fd);
pthread_exit(NULL);
}


I run
#. / qq_server shown below
enter an infinite loop
chat begin

Then I run. / qq_client shown below
client socket id is 3
I then enter the number 45 after the carriage return did not reflect what the server side,

Then I wrote on the server side letters such as: abc
appear

server has input #
write error :: Transport endpoint is not connected

client read error occurs prompt information

Which heroes, help me to see how wrong, brother grateful, this semester just learning linux network programming, and thought they want, change the procedure, if any, low-error, do not laugh ah ! ^ _ ^!!

------ For reference only ---------------------------------- -----
I know how wrong, I'll do accept () doing with no clear, thank you! ! !
------ For reference only -------------------------------------- -
Hello I have encountered this problem and you almost had to call setsockopt () function is still there after ADDRESS ALREADY IN USE . . Do you now understand the reason of it. . You can not delay the next few minutes to tell me. . . Grateful
------ For reference only ----------------------------------- ----
code how you like?
------ For reference only -------------------------------------- -
Hello, I have encountered the same problem, help me to see it? Thank you

int main()
{int on,ret,len;
int server_sockfd;
int client_sockfd;
struct sockaddr_in my_addr;  
struct sockaddr_in remote_addr;
int sin_size;   
char* rec;
char buf[BUFSIZ];
memset(&my_addr,0,sizeof(my_addr));
my_addr.sin_family=AF_INET;
my_addr.sin_addr.s_addr=INADDR_ANY;
my_addr.sin_port=htons(PORT); 
server_sockfd=socket(AF_INET,SOCK_STREAM,0);   
on=1;   
setsockopt(server_sockfd,SOL_SOCKET,SO_REUSEADDR,(char*)&on,sizeof(on));     ret=bind(server_sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr));   
if(ret<0){  perror("bind"); } 
listen(server_sockfd,SOMAXCONN);
sin_size=sizeof(struct sockaddr_in);  
while(1) { 
if((client_sockfd=accept(server_sockfd,(struct sockaddr *)&remote_addr,&sin_size))<0) 
{   perror("accept");  }    
printf("accept client %s\n",inet_ntoa(remote_addr.sin_addr)); 
//len=send(client_sockfd,"Welcome to my server\n",21,0);//send welcom info    len=recv(client_sockfd,buf,BUFSIZ,0); 
buf[len]='\0'; 
printf("%s",buf); 
rec=strtok(buf,"\n");  
return rec; 
if(send(client_sockfd,buf,len,0)<0) 
{   perror("write");  } 
close(client_sockfd);
}
close(server_sockfd);
return 0;
}

------ For reference only ----------------------------------- ----
@ 9 #
Upstairs code this format, see who ah?

没有评论:

发表评论