Join cainiao in exploring network programming for the National embedded experiment

Source: Internet
Author: User
Tags socket error htons

1. TCP Program Design

Code 1 server:

#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <netdb.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h> #define portnumber 3333 int main(int argc, char *argv[]){   int sockfd, new_fd;   struct sockaddr_in server_addr;   struct sockaddr_in client_addr;   int sin_size;   int nbytes;   char buffer[1024];      //AF_INET: IPV4, SOCK_STREAM: TCP   if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)    {        fprintf(stderr, "Socket error:%s\n\a", strerror(errno));       exit(1);    }    bzero(&server_addr, sizeof(struct sockaddr_in));   server_addr.sin_family = AF_INET;   server_addr.sin_addr.s_addr = htonl(INADDR_ANY);   server_addr.sin_port = htons(portnumber);    if(bind(sockfd, (struct sockaddr *) (&server_addr), sizeof(structsockaddr)) == -1)    {       fprintf(stderr, "Bind error: %s\n\a", strerror(errno));       exit(1);    }    if(listen(sockfd, 5) == -1)    {       fprintf(stderr, "Listen error: %s\n\a", strerror(errno));       exit(1);            }     while(1)    {       sin_size = sizeof(struct sockaddr_in);       if((new_fd = accept(sockfd, (struct sockaddr *)(&client_addr),&sin_size)) == -1)       {            fprintf(stderr, "Accept error:%s\n\a", strerror(errno));           exit(1);       }        fprintf(stderr, "Server get connection from %s\n",(char*)inet_ntoa(client_addr.sin_addr));        if((nbytes = read(new_fd, buffer, 1024)) == -1)        {           fprintf(stderr, "Read Error: %s\n", strerror(errno));           exit(1);       }        buffer[nbytes] = '\0';        printf("Server received %s\n", buffer);        close(new_fd);    }    close(sockfd);      return 0;}

Code 2 client:

#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <netdb.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h> #define portnumber 3333 int main(int argc, char *argv[]){   int sockfd;   char buffer[1024];   struct sockaddr_in server_addr;   struct hostent *host;    if(argc != 2)    {       fprintf(stderr, "Usage: %s hostname \a\n", argv[0]);       exit(1);    }    if((host = gethostbyname(argv[1])) == NULL)    {        fprintf(stderr, "Gethostname Error:%s\a\n", strerror(errno));       exit(1);    }    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)    {       fprintf(stderr, "Socket Error: %s\a\n", strerror(errno));       exit(1);    }     bzero(&server_addr, sizeof(server_addr));   server_addr.sin_family = AF_INET;   server_addr.sin_port = htons(portnumber);   server_addr.sin_addr = *((struct in_addr *) host->h_addr);    if(connect(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr))== -1)    {       fprintf(stderr, "Connect Error: %s\a\n", strerror(errno));       exit(1);    }    printf("Please input char: \n");    fgets(buffer, 1024, stdin);   write(sockfd, buffer, strlen(buffer));    close(sockfd); return 0;}

Makefile:

CC = gcc CURTDIR = $(shell pwd)TARGET = tcp_client#TARGET = tcp_server %.o:%.c       $(CC)-c $(EXTRAFLAGS) $< -o $@%.o:%.S       $(CC)-c $(EXTRAFLAGS) $< -o $@ .PHONY: all clean $(TARGET): $(TARGET).o       $(CC)  -o $@ $^ clean:       rm-rf $(TARGET) $(TARGET).o

Running result:

eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.1$makegcc -c tcp_server.c -o tcp_server.ogcc -o tcp_server tcp_server.o eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.1$lsMakefile tcp_client.c  tcp_server  tcp_server.c tcp_server.o eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.1$makegcc -c tcp_client.c -o tcp_client.ogcc -o tcp_client tcp_client.o eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.1$lsMakefile tcp_client  tcp_client.c  tcp_client.o tcp_server  tcp_server.c  tcp_server.o  eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.1$./tcp_client 192.0.4.87Please input char:hello mytcp eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.1$./tcp_client 192.0.4.87Please input char:I am back! eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.1$./tcp_serverServer get connection from 192.0.4.87Server received hello mytcp Server get connection from 192.0.4.87Server received I am back!

Summary: when no client is connected, the server program is blocked on the accept function and waits for the connection. When a client is connected, it is blocked on the READ function and waits for the message to be read. After the client sends a message, the server reads the message and continues waiting for a new connection.

 

 

2. UDP Programming

Code 1 server:

#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <netdb.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h> #define portnumber 3333#define MAX_MSG_SIZE 1024 void udps_respon(int sockfd){   struct sockaddr_in addr;   int addrlen, n;   char msg[MAX_MSG_SIZE];    while(1)    {       bzero(msg, sizeof(msg));       addrlen = sizeof(struct sockaddr);       n = recvfrom(sockfd, msg, MAX_MSG_SIZE, 0, (struct sockaddr *)&addr,&addrlen);       msg[n] = 0;       fprintf(stdout, "Server had received %s\n", msg);    }} int main(int argc, char *argv[]){   int sockfd;   struct sockaddr_in addr;      //AF_INET: IPV4, SOCK_DGRAM: UDP   if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)    {       fprintf(stderr, "Socket error: %s\n\a", strerror(errno));       exit(1);    }    bzero(&addr, sizeof(struct sockaddr_in));    addr.sin_family= AF_INET;   addr.sin_addr.s_addr = htonl(INADDR_ANY);   addr.sin_port = htons(portnumber);    if(bind(sockfd, (struct sockaddr *) (&addr), sizeof(structsockaddr)) == -1)    {       fprintf(stderr, "Bind error: %s\n\a", strerror(errno));       exit(1);    }    udps_respon(sockfd);    close(sockfd);         return 0;}

Code 2 client:

#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <netdb.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h> #define portnumber 3333#define MAX_BUF_SIZE 1024 void udpc_requ(int sockfd, const structsockaddr_in *addr, int len){   char buffer[MAX_BUF_SIZE];   int n;    while(1)    {       printf("Please input char: \n");        fgets(buffer, MAX_BUF_SIZE, stdin);       sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr*)addr, len);       bzero(buffer, MAX_BUF_SIZE);    }} int main(int argc, char *argv[]){   int sockfd;   struct sockaddr_in addr;    if(argc != 2)    {       fprintf(stderr, "Usage: %s hostname \a\n", argv[0]);       exit(1);    }    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)    {       fprintf(stderr, "Socket Error: %s\a\n", strerror(errno));       exit(1);    }     bzero(&addr,sizeof(struct sockaddr_in));   addr.sin_family = AF_INET;   addr.sin_port = htons(portnumber);   if(inet_aton(argv[1], &addr.sin_addr) < 0)    {       fprintf(stderr, "IP error:%s\n", strerror(errno));       exit(1);    }     udpc_requ(sockfd, &addr, sizeof(struct sockaddr_in));     close(sockfd); return 0;}

Makefile:

CC = gcc CURTDIR = $(shell pwd)TARGET = udp_client#TARGET = udp_server %.o:%.c       $(CC)-c $(EXTRAFLAGS) $< -o $@%.o:%.S       $(CC)-c $(EXTRAFLAGS) $< -o $@ .PHONY: all clean $(TARGET): $(TARGET).o       $(CC)  -o $@ $^ clean:       rm-rf $(TARGET) $(TARGET).o 

Running result:

eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.2$makegcc -c udp_server.c -o udp_server.ogcc -o udp_server udp_server.o eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.2$makegcc -c udp_client.c -o udp_client.ogcc -o udp_client udp_client.o eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.2$./udp_client 192.0.4.87Please input char:hello myudp             Please input char:good-buyPlease input char: eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.2$./udp_serverServer had received hello myudp Server had received good-buy 

Conclusion: when no client is connected, the server is blocked and blocked on the recvfrom function. When a client is connected. After the client sends a message, the server reads the message and prints it.

 

 

3. Concurrent Server Design

Code 1 server:

#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <netdb.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h>#include <pthread.h> #define portnumber 3333 void *thr_fn(void *arg){   int size, j;   char recv_buff[1024];   int *parg = (int *)arg;   int new_fd = *parg;      printf("new_fd = %d\n", new_fd);    while((size = read(new_fd, recv_buff, 1024)) > 0)    {       if(recv_buff[0] == '@')           break;              printf("Message from client(%d): %s\n", size, recv_buff);              for(j = 0; j < size; j++)       {           recv_buff[j] = toupper(recv_buff[j]);       }       write(new_fd, recv_buff, size);        memset(recv_buff, 0, sizeof(recv_buff));    }    close(new_fd);    return NULL;} int main(int argc, char *argv[]){   int listen_sockfd;   int com_fd;   int i;   static char recv_buff[1024];   int len;   int port;   pthread_t tid;   socklen_t clt_addr_len;    struct sockaddr_in server_addr;   struct sockaddr_in client_addr;     if(argc != 2)    {       printf("Usage: %s port\n", argv[0]);       return 1;    }    port = atoi(argv[1]);    if((listen_sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)    {       fprintf(stderr, "Socket error: %s\n\a", strerror(errno));       exit(1);    }    memset(&server_addr, 0, sizeof(server_addr));   server_addr.sin_family = AF_INET;   server_addr.sin_addr.s_addr = htonl(INADDR_ANY);   server_addr.sin_port = htons(port);    if(bind(listen_sockfd, (struct sockaddr *) (&server_addr),sizeof(struct sockaddr)) == -1)    {       fprintf(stderr, "Bind error: %s\n\a", strerror(errno));       close(listen_sockfd);       exit(1);    }    if(listen(listen_sockfd, 5) == -1)    {       fprintf(stderr, "Listen error: %s\n\a", strerror(errno));       close(listen_sockfd);       exit(1);            }    while(1)    {       len = sizeof(client_addr);       com_fd = accept(listen_sockfd, (struct sockaddr*)&client_addr,&len);       if(com_fd < 0)       {           if(errno == EINTR)           {                continue;           }            else           {                perror("cannot acceptclient connect request\n");                close(listen_sockfd);                return 1;           }       }       printf("com_fd = %d\n", com_fd);        if((pthread_create(&tid, NULL, thr_fn, &com_fd)) == -1)       {           perror("pthread_create error");           close(listen_sockfd);           close(com_fd);           return 1;       }    }    return 0;}

Code 2 client:

#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <netdb.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h>#include <unistd.h>#include <sys/un.h> #define portnumber 3333 int main(int argc, char *argv[]){   int connect_fd;   int ret;   char snd_buf[1024];   int i;   int port;   int len;   static struct sockaddr_in server_addr;    if(argc != 3)    {       fprintf(stderr, "Usage: %s ip \a\n", argv[0]);       exit(1);    }    port = atoi(argv[2]);    if((connect_fd = socket(PF_INET, SOCK_STREAM, 0)) == -1)    {       fprintf(stderr, "Socket Error: %s\a\n", strerror(errno));       exit(1);    }    bzero(&server_addr, sizeof(server_addr));   server_addr.sin_family = AF_INET;   server_addr.sin_addr.s_addr = inet_addr(argv[1]);   server_addr.sin_port = htons(port);    if(connect(connect_fd, (struct sockaddr *)(&server_addr),sizeof(struct sockaddr)) == -1)    {       fprintf(stderr, "Connect Error: %s\a\n", strerror(errno));       exit(1);    }    memset(snd_buf, 0, 1024);      while(1)    {       printf("input message: \n");        memset(snd_buf, 0, sizeof(snd_buf));              fgets(snd_buf, 1024, stdin);                len = strlen(snd_buf);        write(connect_fd, snd_buf, len);             len = read(connect_fd, snd_buf, len);       if(len > 0)           printf("Message from server: %s\n", snd_buf);       if(snd_buf[0] == '@')           break;    }      close(connect_fd); return 0;}

 

Makefile:

CC = gcc CURTDIR = $(shell pwd)#TARGET = thread_clientTARGET = thread_server %.o:%.c       $(CC)-c $(EXTRAFLAGS) $< -o $@%.o:%.S       $(CC)-c $(EXTRAFLAGS) $< -o $@ .PHONY: all clean $(TARGET): $(TARGET).o       $(CC)  -o $@ $^ -lpthread clean:       rm-rf $(TARGET) $(TARGET).o 

 

Running result:

eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.3$makegcc -c thread_server.c -o thread_server.ogcc -o thread_server thread_server.o -lpthread eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.3$lsMakefile thread_client.c thread_server thread_server.c  thread_server.o  eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.3$makegcc -c thread_client.c -o thread_client.ogcc -o thread_client thread_client.o -lpthread eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.3$lsMakefile thread_client thread_client.c thread_client.o  thread_server  thread_server.c  thread_server.o  eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.3$./thread_client 192.0.4.87 2222input message:hello, i am the 1stMessage from server: HELLO, I AM THE 1ST input message:@eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.3$./thread_client 192.0.4.87 2222input message:hello, i am the 1st, i am backMessage from server: HELLO, I AM THE 1ST, IAM BACK input message:@  eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.3$./thread_client 192.0.4.87 2222input message:hi, i am the 2ndMessage from server: HI, I AM THE 2ND input message:@    eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.3$./thread_server 2222com_fd = 4new_fd = 4Message from client(20): hello, i am the1st com_fd = 5new_fd = 5Message from client(17): hi, i am the 2nd com_fd = 6new_fd = 6Message from client(31): hello, i am the1st, i am back 

Conclusion: The concurrent server uses multiple threads or multiple processes, so it can accept connections from multiple clients. The cyclic server can accept another connection only after one connection is disconnected, because the server process is executing the message sending and receiving operation on the client and cannot continue to receive new connections.

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.