首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >服务器突然终止(非socket上的socket操作)

服务器突然终止(非socket上的socket操作)
EN

Stack Overflow用户
提问于 2013-09-12 04:52:16
回答 1查看 1.1K关注 0票数 0

当我从客户端(使用本地主机ubuntu/多个控制台)发送消息时,.I只能看到来自第二个控制台(客户端)或更高版本的消息,而不能看到来自first.And的消息。连接在消息显示后终止,否则对于第一个客户端,它只是等待。

C++的服务器代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#define PORT "3490"
#define STDIN  0
#define STDOUT 1
char *opt;

void *get_in_addr(struct sockaddr *sa)
{
    if (sa->sa_family == AF_INET) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }
    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int main(void)
{
    fd_set master;
    fd_set read_fds;
    int fdmax;
    // master file descriptor list
    // temp file descriptor list for select()
    // maximum file descriptor number
    int listener;
    // listening socket descriptor
    int newfd;
    // newly accept()ed socket descriptor
    struct sockaddr_storage remoteaddr; // client address
    socklen_t addrlen;
    char buf[256];
    int nbytes;
    // buffer for client data
    char remoteIP[INET6_ADDRSTRLEN];
    int yes=1;
    int i, j, rv;
    // for setsockopt() SO_REUSEADDR, below
    struct addrinfo hints, *ai, *p;
    FD_ZERO(&master);
    FD_ZERO(&read_fds);
    // clear the master and temp sets
    // get us a socket and bind it
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;
    if ((rv = getaddrinfo(NULL, PORT, &hints, &ai)) != 0) {
        fprintf(stderr, "selectserver: %s\n", gai_strerror(rv));
        exit(1);
    }
    for(p = ai; p != NULL; p = p->ai_next) {
        listener = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
        if (listener < 0) {
            continue;
        }
        // lose the pesky "address already in use" error message
        setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
        if (bind(listener, p->ai_addr, p->ai_addrlen) < 0) {
            close(listener);
            continue;
        }

        break;
    }
    // if we got here, it means we didn't get bound
    if (p == NULL) {
        fprintf(stderr, "selectserver: failed to bind\n");
        exit(2);
    }
    freeaddrinfo(ai); // all done with this
    // listen
    if (listen(listener, 10) == -1) {
        perror("listen");
        exit(3);
    }
    // add the listener to the master set
    FD_SET(listener, &master);
    FD_SET(STDIN,&master);
    // keep track of the biggest file descriptor
    fdmax = listener; // so far, it's this one
    // main loop
    for(;;) {
        read_fds = master; // copy it
        if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
            perror("select");
            exit(4);
        }
        // run through the existing connections looking for data to read
        for(i = 0; i <= fdmax; i++) {
            if (FD_ISSET(i, &read_fds)) { // we got one!!
            if (i == listener) {
                // handle new connections
                addrlen = sizeof remoteaddr;
                newfd = accept(listener,
                               (struct sockaddr *)&remoteaddr,
                               &addrlen);
                if (newfd == -1) {
                    perror("accept");
                } else {
                FD_SET(newfd, &master); // add to master set
                if (newfd > fdmax) {
                    // keep track of the max
                    fdmax = newfd;
                }
                printf("selectserver: new connection from %s on "
                       "socket %d\n",inet_ntop(remoteaddr.ss_family,
                        get_in_addr((struct sockaddr*)&remoteaddr),
                        remoteIP, INET6_ADDRSTRLEN),
                        newfd);
                }
            } else {

                // handle data from a client
                if ((nbytes = recv(i, buf, sizeof buf, 0)) <= 0) {
                    // got error or connection closed by client
                    if (nbytes == 0) {
                        // connection closed

                        printf("selectserver: socket %d hung up\n", i);
                    } else {
                        perror("recv");
                    }
                    close(i); // bye!
                    FD_CLR(i, &master); // remove from master set
                } else {
                    if(i==STDIN){
                        printf("Goodbye");
                    }
                    // we got some data from a client
                    for(j = 0; j <= fdmax; j++) {
                        // send to everyone!
                        if (FD_ISSET(j, &master)) {
                            // except the listener and ourselves
                            if (j != listener && j != i) {
                                if (send(j, buf, nbytes, 0) == -1) {
                                    perror("send");
                                }

                            }
                        }
                    }
                }
            } // END handle data from client
            } // END got new incoming connection
        } // END looping through file descriptors
    } // END for(;;)--and you thought it would never end!
    return 0;
}

//新代码已修改,一旦通过读取获取stdin数据,则不会响应任何其他连接,可能是由于阻塞请帮助

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/time.h>


#define TRUE 1
#define FALSE 0

//Var
int mode,info;
int PORT;

char *ip_host;
int i,len,rc,on=1;
int listen_sd,max_sd,new_sd;
int desc_ready,end_server=FALSE;
int close_conn;
char buffer[256];
//struct sockaddr_in  addr;
struct timeval timeout;
fd_set master_set,working_set;
struct sockaddr_storage remoteaddr; // client addres//s
socklen_t addrlen;
char remoteIP[INET6_ADDRSTRLEN];
char s[INET6_ADDRSTRLEN];
struct addrinfo hints, *loadinfo, *ptr;


void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET) {
return &(((struct sockaddr_in*)sa)->sin_addr);
}
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}


void servcl_memset(){
memset(&hints, 0, sizeof(hints));
hints.ai_family= AF_UNSPEC;
hints.ai_socktype= SOCK_STREAM;
}

void cl_connect()
{
for(ptr = loadinfo; ptr != NULL; ptr = ptr->ai_next) {
  if ((listen_sd = socket(ptr->ai_family, ptr->ai_socktype,ptr->ai_protocol)) == -1) {
  perror("client: socket");
  continue;
  }

 if (connect(listen_sd, ptr->ai_addr, ptr->ai_addrlen) == -1) {
 close(listen_sd);
 perror("client: connect");
 continue;
 }

break;
}

if (ptr == NULL) {
fprintf(stderr, "client: failed to connect(bind)\n");
exit(0);
}
inet_ntop(ptr->ai_family, get_in_addr((struct sockaddr *)ptr->ai_addr),s, sizeof s);
printf("client: connecting to %s\n", s);
freeaddrinfo(loadinfo); // all done with this structure
}



void init_socket(){
for(ptr = loadinfo; ptr != NULL; ptr = ptr->ai_next) {

if ((listen_sd = socket(ptr->ai_family, ptr->ai_socktype,ptr->ai_protocol)) == -1) {
perror("server: socket");
continue;
}

rc = setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR,(char *)&on, sizeof(on));
if (rc < 0)
{
perror("setsockopt() failed");
close(listen_sd);
continue;
}

rc = bind(listen_sd,ptr->ai_addr,ptr->ai_addrlen);
if (rc < 0)
{
perror("bind() failed");
close(listen_sd);
continue;
}
break;

}//End For

if (ptr == NULL) {
fprintf(stderr, "client/server: failed to connect(bind)\n");
exit(0);
}
freeaddrinfo(loadinfo); // all done with this structure
}

void unblock(){
rc = ioctl(listen_sd, FIONBIO, (char *)&on);
if (rc < 0)
{
perror("ioctl() failed");
close(listen_sd);
exit(-1);
}
}

void sock_listen(){
rc = listen(listen_sd, 32);
if (rc < 0)
{
perror("listen() failed");
close(listen_sd);
exit(-1);
}
/*************************************************************/
/* Initialize the master fd_set
*/
/*************************************************************/
FD_ZERO(&master_set);
max_sd = listen_sd;
FD_SET(0,&master_set);
FD_SET(listen_sd, &master_set);
}

void conn_timeout(){
timeout.tv_sec = 3 * 60;
timeout.tv_usec = 0;
}


/*void client_listen(){
do
{
memcpy(&working_set, &master_set, sizeof(master_set));
printf("Waiting on select()...\n");
rc = select(max_sd + 1, &working_set, NULL, NULL, &timeout);

if (rc < 0)
{
perror(" select() failed");
break;
}

if (rc == 0)
{
printf(" select() timed out. End program.\n");
break;
}

desc_ready = rc;
*/

void start_listen(){
do
{
memcpy(&working_set, &master_set, sizeof(master_set));
printf("Waiting on select()...\n");
rc = select(max_sd + 1, &working_set, NULL, NULL, &timeout);

if (rc < 0)
{
perror(" select() failed");
break;
}

if (rc == 0)
{
printf(" select() timed out. End program.\n");
break;
}

desc_ready = rc;
for (i=0; i <= max_sd && desc_ready > 0; ++i)
{
if (FD_ISSET(i, &working_set))
{
desc_ready -= 1;
if (i == listen_sd)
{
printf(" Listening socket is readable\n");

do
{
addrlen = sizeof remoteaddr;
new_sd = accept(listen_sd, (struct sockaddr *)&remoteaddr,&addrlen);
if (new_sd < 0)
{
if (errno != EWOULDBLOCK)
{
perror(" accept() failed");
end_server = TRUE;
}
break;
}

printf(" New incoming connection - %d\n", new_sd);
printf("selectserver: new connection from %s on "
"socket %d\n",
inet_ntop(remoteaddr.ss_family,
get_in_addr((struct sockaddr*)&remoteaddr),
remoteIP, INET6_ADDRSTRLEN),
new_sd);

FD_SET(new_sd, &master_set);
if (new_sd > max_sd)
max_sd = new_sd;
} while (new_sd != -1);
}

else
{
printf(" Descriptor %d is readable\n", i);
close_conn = FALSE;

//do
//{
rc = read(i, buffer, sizeof(buffer)-1);
if (rc < 0)
{
 if (errno != EWOULDBLOCK)
{
perror(" recv() failed");
close_conn = TRUE;
}
break;
}

if (rc == 0)
{
printf(" Connection closed\n");
close_conn = TRUE;
break;
}

len = rc;
printf(" %d bytes received\n", len);
if (i==0)i=1;
rc = write(i, buffer, len);
if (i==1)i=0;
if (rc < 0)
{
perror(" send() failed");
close_conn = TRUE;
break;
}
//} while (TRUE);

if (close_conn)
{
close(i);
FD_CLR(i, &master_set);
if (i == max_sd)
{
while (FD_ISSET(max_sd, &master_set) == FALSE)
max_sd -= 1;
}
}
} /* End of existing connection is readable */
} /* End of if (FD_ISSET(i, &working_set)) */
} /* End of loop through selectable descriptors */
end_server==TRUE;} while (end_server == FALSE);
}

void conn_close(){
for (i=0; i <= max_sd; ++i)
{
if (FD_ISSET(i, &master_set))
close(i);
}
}


void cl_socket() {
printf("Please enter the message: ");
do
{
memcpy(&working_set, &master_set, sizeof(master_set));
printf("Waiting on select()...\n");
rc = select(max_sd + 1, &working_set, NULL, NULL,NULL);

if (rc < 0)
{
perror(" select() failed");
break;
}


desc_ready = rc;
for (i=0; i <= max_sd && desc_ready > 0; ++i)
{
 if (FD_ISSET(i, &working_set))
  {
    desc_ready -= 1;
    printf(" Descriptor %d is readable\n", i);
    close_conn = FALSE;
  do  
    {
    fgets(buffer,255,stdin);
    rc = write(listen_sd, buffer,strlen(buffer));
    if (rc < 0)
     {
      perror(" send() failed");
      close_conn = TRUE;
     }

    rc = read(listen_sd, buffer, sizeof(buffer)-1);
    if (rc < 0)
    {
     if (errno != EWOULDBLOCK)
       {
        perror(" recv() failed");
        close_conn = TRUE;
       }

     }

      if (rc == 0)
      {
      printf(" Connection closed\n");
      close_conn = TRUE;
      }

len = rc;
printf(" %d bytes received\n", len);
 } while (TRUE);

if (close_conn)
{
 close(i);
 FD_CLR(i, &master_set);
 if (i == max_sd)
 {
 while (FD_ISSET(max_sd, &master_set) == FALSE)
 max_sd -= 1;
 }
}

}//Working set
}//For loop

end_server==TRUE;} while (end_server == FALSE);

}

main(int argc,char * argv[])
{
mode=atoi(argv[1]);
PORT=atoi(argv[2]);
ip_host=(argv[3]);
servcl_memset();
 if (mode ==1){
               printf("In client mode\n");
           if ((info = getaddrinfo(argv[3], argv[2], &hints, &loadinfo)) != 0) {
           fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(info));
               return 1;
                    }
              cl_connect();  
              unblock();
              conn_timeout();
              cl_socket();
              conn_close();
              }
  else {
         printf("In server mode\n");
         hints.ai_flags=AI_PASSIVE;
         if ((info = getaddrinfo(NULL, argv[2], &hints, &loadinfo)) != 0) {
         fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(info));
         return 1;
         }
         init_socket();
         unblock();
         sock_listen();
         conn_timeout();
         start_listen();
         conn_close();
       }

}



/*

*/

我还有另一个客户端,我正在使用它进行测试。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h> 

void error(const char *msg)
{
    perror(msg);
    exit(0);
}

int main(int argc, char *argv[])
{
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    char buffer[256];
    if (argc < 3) {
       fprintf(stderr,"usage %s hostname port\n", argv[0]);
       exit(0);
    }
    portno = atoi(argv[2]);
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) 
        error("ERROR opening socket");
    server = gethostbyname(argv[1]);
    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host\n");
        exit(0);
    }
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *)server->h_addr, 
         (char *)&serv_addr.sin_addr.s_addr,
         server->h_length);
    serv_addr.sin_port = htons(portno);
    if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) 
        error("ERROR connecting");
    printf("Please enter the message: ");
    bzero(buffer,256);
    fgets(buffer,255,stdin);
    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0) 
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",buffer);
    close(sockfd);
    return 0;
}
EN

回答 1

Stack Overflow用户

发布于 2013-09-12 05:31:57

这实际上是一个linux问题,因为您正在尝试使用recvsend来读取和写入STDIN (它可能是一个终端,而不是一个套接字)。与大多数UNIX变体不同,在Linux中,sendrecv只能在套接字上使用,而不能在任何文件描述符上使用。对于终端,您需要使用readwrite

还有一个问题是,写入STDIN很奇怪--通常情况下,您只能从STDIN读取并写入STDOUT。但只要STDIN是像终端一样的东西,你可以向它写东西,那就没问题了。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18755589

复制
相关文章
linux网络编程系列(七)--如何将socket设置成非阻塞的,非阻塞socket与阻塞的socket在收发数据上的区别
socket函数创建socket默认是阻塞的,也可以增加选项将socket设置为非阻塞的:
cpp加油站
2021/04/16
3.5K0
linux网络编程系列(七)--如何将socket设置成非阻塞的,非阻塞socket与阻塞的socket在收发数据上的区别
Python 开发web服务器,socket非堵塞模式
在开发web服务器接受http请求的时候,socket在recv等待接受数据的时候,服务端是堵塞的。 用于等待http发送过来的数据。 那么这个等待,其实也是会占用服务端的资源的。 为了节省这个资源,可以采用非堵塞的方式来进行socket等待监听,就是每次轮询监听一下,并不会堵塞等待。
Devops海洋的渔夫
2019/05/31
1.1K0
Python的简单socket操作
import socket host = '' port = 12345 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind((host, port)) s.listen(1) print "Server is running on port %d; press Ctrl-C to terminate." % port
py3study
2020/01/07
3040
5. Python 开发web服务器,socket非堵塞模式
最近老李还写了一个用codemirror在线编写python以及执行调用的示例。留在传完这个系列之后再发布吧。
Devops海洋的渔夫
2022/01/17
5130
5. Python 开发web服务器,socket非堵塞模式
提高 Linux 上 socket 性能
在开发 socket 应用程序时,首要任务通常是确保可靠性并满足一些特定的需求。利用本文中给出的 4 个提示,您就可以从头开始为实现最佳性能来设计并开发 socket 程序。本文内容包括对于 Sockets API 的使用、两个可以提高性能的 socket 选项以及 GNU/Linux 优化。
一见
2018/08/07
4.2K0
python中socket与socket
一、socket模块 socket又叫套接字,是网络编程中的一个基本组件,是两个端点的程序之间的“信息通道”程序可分布在不同的计算机上(通过网络连接),通过socket套接字相互发送信息。python中的大多数的网络编程都 隐藏了socket模块的基本细节。 python中通过socket模块完成网络编程的套接字实现,一个套接字就是socket模块中的socket类的一个实例。socket实例化需要三个参数分别是family(ipv4,ipv6,unix)其中默认是ipv4 "socket.AF_INET",第二个参数是流,默认是socket.SOC_STREAM表示tcp,或socket.SOCK_DGRAM,第三个参数是协议,默认是0,使用默认即可。因此实际上实例化出一个套接字,只需要二个参数。
py3study
2020/01/09
1.5K0
python中socket与socket
python socket 进行文件上
#coding:utf-8 import SocketServer import os import datetime import MySQLdb class mysql: def init(self): self.connect = MySQLdb.connect( host = '192.168.221.203', user = 'hall', passwd = '520157', port = 3306, db = 'info', charset = 'utf8' ) def mysql_create_table_info(self): cursor = self.connect.cursor() sql = """create table if not exists info( action char(20), actin_time varchar(40), file_size varchar(20), file_name varchar(40), operation_user char(20) )""" cursor.execute(sql) cursor.close() self.connect.commit() self.connect.close() def mysql_create_table_user(self): cursor = self.connect.cursor() sql_user = """create table if not exists user( user varchar(20), passwd varchar(40) )""" cursor.execute(sql_user) data = """insert into user values( "hall", "hall"), ("hexulin", "hexulin")""" cursor.execute(data) cursor.close() self.connect.commit() self.connect.close()
py3study
2020/01/10
4380
Socket
Socket 据交换,这个双向连接的一端称为一个Socket java.net包中定义的两个类Socket和ServerSocket,分别用来实现双向连接的client和server端 建立连接时所需的寻址信息为远程计算机的ip地址和端口号(Port number) //Server端 import java.net.*; import java.io.*; public class TcpServer { public static void main(String[] args) throws
mathor
2018/07/03
1.1K0
解决socket服务器(chatserver)的问题
3.在控制器中,切换到解压后文件的路径。(   cd /###/##/Twisted-13.1.0.   )
用户1451823
2018/09/13
6560
Python Socket编程Python Socket编程
Python Socket编程 在使用Python做socket编程时,由于需要使用阻塞(默认)的方式来读取数据流,此时对于数据的结束每次都需要自己处理,太麻烦。并且网上也没找到太好的封装,所以就自己写了个简单的封装。 封装思路 客户端每次请求均发送一个 SocketRequest 对象,其中封装具体的数据,这里使用json。对于要发送的数据,会自动添加一个结束符标识(EOF = '0x00')。 服务器端接收数据时,根据结束符标识来生成完整的数据,并解包成 SocketRequest 对象。 服务器端根据
kongxx
2018/05/14
2.2K0
socket rst_socket通信编程
可以看到客户端通过connect方法发起三次握手,发送完第一个SYN分节以后,收到来自服务端的RST分节;
全栈程序员站长
2022/11/14
1.7K0
socket rst_socket通信编程
socket常用函数_socket recv函数
在linux下,使用socketpair函数能够创建一对套节字进行进程间通信(IPC)。
全栈程序员站长
2022/11/04
1.5K0
socket
Socket是对TCP/UDP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/UDP协议。
Helloted
2022/06/06
7870
ioctlsocket() 用法 socket recvfrom 阻塞 非阻塞 设置
不知道大家有没有遇到过这种情况,当socket进行TCP连接的时候(也就是调用connect时),一旦网络不通,或者是ip地址无效,就可能使整个线程阻塞。一般为30秒(我测的是20秒)。如果设置为非阻塞模式,能很好的解决这个问题,我们可以这样来设置非阻塞模式:
战神伽罗
2019/08/29
3.8K0
[python网络编程]socket
1.在建立socket对象的时候,需要告诉系统两件事情 1.1 通信的类型是什么(IPv4/IPv6等) 1.2 使用的协议是什么?(TCP/UDP等)
py3study
2020/01/08
9420
Socket
{tabs-pane label="服务端"} public class Demo804_1 { public static void main(String[] args)throws IOException { ServerSocket ss=new ServerSocket(520);//监听一个端口号 System.out.println("监听服务开启"); for (;;){ Socket socket=ss.a
await
2021/09/09
6400
从linux源码看socket的阻塞和非阻塞
由于网络协议非常复杂,内核里面用到了大量的面向对象的技巧,所以我们从创建连接开始,一步一步追述到最后代码的调用点。
呆呆
2021/05/20
4.7K0
socket技术详解(看清socket编程)
socket编程是网络常用的编程,我们通过在网络中创建socket关键字来实现网络间的通信,通过收集大量的资料,通过这一章节,充分的了解socket编程,文章用引用了大量大神的分析,加上自己的理解,做个总结性的文章
全栈程序员站长
2022/09/14
3.4K0
socket技术详解(看清socket编程)
点击加载更多

相似问题

"binding to socket error“后无法终止socket

220

socket终止后维护服务器

32

Socket.Close()不会终止Socket.Accept()!

10

如何立即终止阻塞socket IO操作的线程?

11

Socket服务器问题: socket服务器崩溃

15
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文