Linux Socket Talkclient Talkserver example

Source: Internet
Author: User

Tag: input int string cannot main char* argv ready hint

Cleint:

#define _gnu_source 1#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <assert.h> #include <stdio.h> #include <unistd.h> #include <string.h > #include <stdlib.h> #include <poll.h> #include <fcntl.h> #define BUFFER_SIZE int main (int argc, C        har* argv[]) {if (argc <= 2) {printf ("Usage:%s ip_address port_number\n", basename (Argv[0]));    return 1;    } const char* IP = argv[1];     int port = atoi (argv[2]);    struct sockaddr_in server_address;    Bzero (&server_address, sizeof (server_address));    server_address.sin_family = af_inet;    Inet_pton (Af_inet, IP, &server_address.sin_addr);     Server_address.sin_port = htons (port);    int SOCKFD = socket (pf_inet, sock_stream, 0);    ASSERT (sockfd >= 0);    Here's use block mode connect socket, there'll be minutes timeout if failed. if (Connect (sockfd, struct sockaddr*) &server_address, sizeof (server_address)) < 0) {printf ("Connection failed\n");        Close (SOCKFD);    return 1;    } POLLFD fds[2]; FDS[0].FD = 0;    stdin fds[0].events = Pollin;    fds[0].revents = 0;    FDS[1].FD = SOCKFD;    Why don ' t concern about Pollout event? fds[1].events = Pollin | Pollrdhup; Concern Read & Hangup event fds[1].events = Pollin | Pollrdhup |    Pollout;    fds[1].revents = 0;    Char Read_buf[buffer_size];    int pipefd[2];    int ret = pipe (PIPEFD);     ASSERT (Ret! =-1);        while (1) {ret = poll (FDS, 2,-1);            if (Ret < 0) {printf ("poll failure\n");        Break  }//connection is hang-up by peer if (fds[1].revents & pollrdhup) {printf ("Server            Close the connection\n ");        Break }//have data from server to read else if (Fds[1].revents & Pollin) {memset(Read_buf, ' buffer_size ');            Recv (FDS[1].FD, Read_buf, buffer_size-1, 0);        printf ("Recv data from server:%s\n", read_buf); } else if (Fds[1].revents & pollout) {//always writable, would print so much a message, so Comm        ENT It//printf ("Connection got Pollout event, it is writable now.\n");  } if (Fds[0].revents & Pollin)//user input--stdin has data to read {//stdin- PIPEFD[1] ret = splice (0, NULL, pipefd[1], NULL, 32768, Splice_f_more |            Splice_f_move); PIPEFD[1]-pipefd[0]-SOCKFD ret = splice (pipefd[0], NULL, SOCKFD, NULL, 32768, Splice_f_more |        Splice_f_move);    }} close (SOCKFD); return 0;}

  

Server

#define _gnu_source 1#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <assert.h> #include <stdio.h> #include <unistd.h> #include <errno.h > #include <string.h> #include <fcntl.h> #include <stdlib.h> #include <poll.h> #define User_    LIMIT 5#define buffer_size 64#define fd_limit 65535 struct client_data{sockaddr_in address;    char* Write_buf;    Char buf[buffer_size]; Client_data (): Write_buf (0) {}};    int setnonblocking (int fd) {int old_option = Fcntl (fd, F_GETFL); int new_option = Old_option |    O_nonblock;    Fcntl (FD, F_SETFL, new_option); return old_option;} int main (int argc, char* argv[]) {if (argc <= 2) {printf ("Usage:%s ip_address port_number\n", Basena        Me (argv[0]);    return 1;    } const char* IP = argv[1];     int port = atoi (argv[2]);    int ret = 0;    struct SOCKADDR_IN address; Bzero (&address, sizeof(address));    address.sin_family = af_inet;    Inet_pton (Af_inet, IP, &address.sin_addr);     Address.sin_port = htons (port);    int LISTENFD = socket (pf_inet, sock_stream, 0);     ASSERT (LISTENFD >= 0);    ret = bind (LISTENFD, (struct sockaddr*) &address, sizeof (address));     ASSERT (Ret! =-1); RET = Listen (LISTENFD, 5);     Backlog=5 assert (Ret! =-1);    client_data* users = new Client_data[fd_limit]; POLLFD fds[user_limit+1];    1 Listen sock FD + 5 user sock fd int user_counter = 0;        for (int i = 1; I <= user_limit; ++i) {fds[i].fd =-1;    fds[i].events = 0;    } FDS[0].FD = LISTENFD; fds[0].events = Pollin | Pollerr;     Read & Error Event fds[0].revents = 0;        while (1) {ret = poll (FDS, user_counter+1,-1);            if (Ret < 0) {printf ("poll failure\n");        Break } for (int i = 0; i < user_counter+1; ++i) {//CLIENT call connect to this server if ((FDS[I].FD = = LISTENFD) && (fds[i].revents & Pollin))                {struct sockaddr_in client_address;                socklen_t client_addrlength = sizeof (client_address);                LISTENFD is block mode by default, but use poll we know the event is ready, accept'll return right now                int CONNFD = Accept (LISTENFD, (struct sockaddr*) &client_address, &client_addrlength);                    if (CONNFD < 0) {printf ("Accept errno is:%d\n", errno);                Continue } if (User_counter >= user_limit) {Const char* info = "Too many use                    RS, so close this connfd returned by accept.\n ";                    printf ("%s", info);                    Send (CONNFD, info, strlen (info), 0);                    Close (CONNFD);                Continue  }              user_counter++;                users[connfd].address = client_address;  Setnonblocking (CONNFD);                CONNFD is Nonblock mode fds[user_counter].fd = CONNFD; fds[user_counter].events = Pollin | Pollrdhup |                pollerr;//concern about Read & Hanguo & Error event at start fds[user_counter].revents = 0;            printf ("comes a new user, now has%d users\n", user_counter);            } else if (Fds[i].revents & Pollerr)//fds[i] has error!                {printf ("Get an error from%d\n", FDS[I].FD);                Char errors[100];                memset (Errors, ' 100 ');                socklen_t length = sizeof (errors); if (getsockopt (FDS[I].FD, Sol_socket, So_error, &errors, &length) < 0) {p                rintf ("Get socket Option failed\n"); } else printf ("%d got an ERror%s\n ", FDS[I].FD, errors);            Continue } else if (Fds[i].revents & Pollrdhup)//fds[i] was hang up by peer {users[fds[                I].FD] = USERS[FDS[USER_COUNTER].FD];                Close (FDS[I].FD);                Fds[i] = Fds[user_counter];                i--;                user_counter--;            printf ("A client left\n");  }//got Readable event else if (Fds[i].revents & pollin) {int CONNFD                = FDS[I].FD;                memset (users[connfd].buf, ' buffer_size ');                ret = recv (CONNFD, Users[connfd].buf, buffer_size-1, 0);                printf ("Get%d bytes of client data:%s from connection:%d\n", ret, Users[connfd].buf, CONNFD); if (Ret < 0)//has error {//nonblock socket, the Read function returns an error eagain, prompting your application to now have no data to read please slightly                    And then try again. If it is a eagain error we just IGnore This error and wait for next Pollin event if (errno! = Eagain) {                        Close (CONNFD);                        USERS[FDS[I].FD] = USERS[FDS[USER_COUNTER].FD];                        Fds[i] = Fds[user_counter];                        i--;                        user_counter--;                    printf ("recv data from a client-ran into error, a client maybe left\n");                }}//if the connection has been gracefully closed and the return value is zero.                    else if (ret = = 0) {//printf ("code should not come to here\n");                    printf ("recv function return 0 indicates the client has gracefully closed and exit.\n");                Need to remove it from FDS??                    } else//server send the data recv from a client to all other clients { for (int j = 1; J <=User_counter;                            ++J) {if (fds[j].fd = = CONNFD) { Continue Don ' t send to self}//Other client's socket is no longer readable at the moment (current Client continues to send multiple messages, these messages will be blocked in the socket Sendbuffer),//To be set to only write!                        Because if you can read it again, if the client sends multiple messages consecutively, the other client will miss the following message!                        Fds[j].events |= ~pollin;                        Fds[j].events |= pollout;                    Users[fds[j].fd].write_buf = Users[connfd].buf;                }}} and Else if (Fds[i].revents & pollout)//got writable Event {                int connfd = FDS[I].FD;                if (! Users[connfd].write_buf) {continue;//no data Send to this client                } ret = Send (CONNFD, Users[connfd].write_buf, strlen (USERS[CONNFD].WRITE_BUF), 0); USers[connfd].write_buf = NULL;                Reset back fds[i].events |= ~pollout;            Fds[i].events |= Pollin;    }}} Delete [] users;    Close (LISTENFD); return 0;}

  

Linux Socket Talkclient Talkserver example

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.