我有简单的TCP服务器程序。在我使用CTRL+C
关闭它并在某些情况下再次重新启动后,telnet客户端会向我报告"connection refused"
。为什么它不总是发生,而只是在某些情况下发生?命令ps
与我的程序无关。
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include<string.h>
void printHex(char *bts);
int main() {
char str[100];
int listen_fd, comm_fd;
struct sockaddr_in servaddr;
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
bzero( &servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htons(INADDR_ANY);
servaddr.sin_port = htons(22000);
printf("binding\n");
bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr));
printf("listening\n");
listen(listen_fd, 10);
printf("accepting\n");
comm_fd = accept(listen_fd, (struct sockaddr*) NULL, NULL);
printf("accep done\n");
int cn = 0;
while(1) {
bzero(str, 100);
printf("will read\n");
int br = read(comm_fd, str, 100);
printf("read done\n");
if (br > 0) {
printHex(str);
} else if (br <= 0) {
comm_fd = accept(listen_fd, (struct sockaddr*) NULL, NULL);
printf("accep done\n");
}
printf("error %d \n", br);
}
}
void printHex(char *bts) {
char *s = bts;
int i = 0;
do {
printf("%02X ", (unsigned char) *bts);
} while (*++bts !=0);
printf("%s\n",s);
}
最佳答案
您应该检查系统调用中的所有返回值:
int res;
res = bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr));
if (res == -1)
// handle error
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listed_fd == -1)
// handle error
很有可能您会发现代码在
bind
系统调用上失败,这意味着您无法在相同的IP地址,协议(protocol)和端口上重用套接字。您可以使用setsockopt
调用来更改此设置:// allow to rebind
int reuseaddr_on = 1;
res = setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR,
&reuseaddr_on, sizeof(reuseaddr_on));
if (res < 0)
{
stderr("Setting of SO_REUSEADDR on server's"
"socket failed");
}
完成后,还应该关闭套接字。
while(1)
{
// your loop
}
res = close(comm_fd);
if (res == -1)
// handle error
正如Linux程序员手册在专门介绍结束调用的页面上所说的那样:
关于c - 与 socket 的连接被拒绝,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34494332/