网络编程之TCP编程

TCP服务器

server.c的作用是接受client的请求,并与client进行简单的数据通信

  2 #include <stdio.h>
  3 #include <sys/socket.h>
  4 #include <netinet/in.h>
  5 #include <errno.h>
  6 #include <unistd.h>
  7 #include <string.h>
  8 #include <sys/types.h>
  9 
 10 #define _PORT_ 9999
 11 #define _BACKLOG_ 10
 12 
 13 int main()
 14 {
 15     int sock = socket(AF_INET, SOCK_STREAM, 0); //SOCK_STREAM表示面向流的传输协议,即TCP协议
 16     if(sock < 0){
 17         printf("create socket error, errno is: %d, errstring is: %s\n", errno,strerror(errno));
 18     }
 19 
 20     struct sockaddr_in server_socket;
 21     struct sockaddr_in client_socket;
 22     bzero(&server_socket, sizeof(server_socket)); //将整个结构体清零
 23     server_socket.sin_family = AF_INET;
 24     server_socket.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY是一个宏,表示本地的任意IP地址
 25     server_socket.sin_port = htons(_PORT_);
 26 
 27     if(bind(sock, (struct sockaddr*)&server_socket, sizeof(struct sockaddr_in)) < 0){
 28         printf("bind error,error code is: %d, error string: %s\n", errno, strerror(errno));
 29         close(sock);
             return 1;
 31     }
 32 
 33     if(listen(sock, _BACKLOG_) < 0){
 34         printf("listen error, error code: %d, error string is : %s\n", errno, strerror(errno));
 35         close(sock);
 36         return 2;
 37     }
 38 
 39     printf("bind and listen success, wait accept...\n");
 40 
 41     for(;;){
 42         socklen_t len = 0;
 43         int client_sock = accept(sock, (struct sockaddr*)&client_socket, &len);
 44         if( client_sock < 0 ){
 45             printf("accept error, errno is: %d, err string is: %s\n", errno, strerror(errno));
 46             close(sock);
 47             return 3;
 48         }
 49 
 50         char buf_ip[INET_ADDRSTRLEN];
 51         memset(buf_ip, '\0', sizeof(buf_ip));
 52         inet_ntop(AF_INET, &client_socket.sin_addr, buf_ip, sizeof(buf_ip));
 53          printf("get connect, ip is: %s port is: %s\n", buf_ip, ntohs(client_socket.sin_port));
 55 
 56         while(1){
 57             char buf[1024];
 58             memset(buf, '\0', sizeof(buf));
 59 
 60             read(client_sock, buf, sizeof(buf));
 61             printf("client:# %s\n",buf);
 62 
 63             printf("server : $ ");
 64 
 65             memset(buf, '\0', sizeof(buf));
 66             fgets(buf, sizeof(buf), stdin);
 67             buf[strlen(buf)-1] = '\0';
 68             write(client_sock, buf, strlen(buf)-1);
 69             printf("please wait...\n");
 70         }
 71     }
 72     close(sock);
 73     return 0;
 74 }
                                                      

TCP客户端

 
  3 #include <stdio.h>
  4 #include <unistd.h>
  5 #include <sys/socket.h>
  6 #include <sys/types.h>
  7 #include <netinet/in.h>
  8 #include <arpa/inet.h>
  9 #include <string.h>
 10 #include <errno.h>
 11 
 12 #define SERVER_PORT 9999
 13 #define SERVER_IP "192.168.0.111"
 14 
 15 
 16 int main(int argc, char* argv[])
 17 {
 18     if(argc != 2){
 19         printf("Usage:client IP\n");
 20     }
 21     char *str = argv[1];
 22     char buf[1024];
 23 
 24     struct sockaddr_in server_sock;
 25     int sock = socket(AF_INET, SOCK_STREAM, 0);
 26     bzero(&server_sock, sizeof(server_sock));
 27     server_sock.sin_family = AF_INET;
 28     inet_pton(AF_INET, SERVER_IP, &server_sock.sin_addr); //将点分十进制转换成32位的IP   地址
30      int ret = connect(sock, (struct sockaddr*)&server_sock, sizeof(server_sock));
 31     if(ret < 0){
 32         perror("connect");
 33         return;
 34     }
 35     printf("connect success...\n");
 36 
 37     while(1){
 38         printf("clinet: # ");
 39         fgets(buf, sizeof(buf), stdin);
 40         buf[strlen(buf)-1] = '\0';
 41         write(sock, buf, sizeof(buf));
 42         if(strncasecmp(buf, "quit", 4) == 0){
 43             printf("quit\n");
 44             break;
 45         }
 46         printf("please wait...\n");
 47         read(sock, buf, sizeof(buf));
 48         printf("server: $ %s\n", buf);
 49     }
 50 
 51     close(sock);
 52 
 53     return 0;
 54 }
                                                

参数说明:


1.. 将整个结构体清零;

2. 设置地址类型为AF_INET;

3. 网络地址为INADDR_ANY, 这个宏表示本地的任意IP地址,因为服务器可能有多个网卡,每个网卡也 可能绑定多个IP 地址, 这样设置可以在所有的IP地址上监听,直到与某个客户端建立了连接时才确定 下来到底用哪个IP 地址;

4. 端⼝口号为SERV_PORT, 我们定义为9999


上述的客户端/服务器·只能处理一个连接,下面是多进程版本

  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <sys/socket.h>
  5 #include <sys/types.h>
  6 #include <netinet/in.h>
  7 #include <arpa/inet.h>
  8 #include <sys/wait.h>
  9 #include <string.h>
 10 #include <unistd.h>
 11 
 12 
 13 void ProcessRequest(int client_fd, struct sockaddr_in *client_addr)
 14 {
 15     char buf[1024];
 16     for(;;){
 17         ssize_t read_size = read(client_fd, buf, sizeof(buf));
 18         if(read_size < 0){
 19             perror("read");
 20             continue;
 21         }
 22         if( read_size == 0 ){
 23             printf("client: %s say bye!\n", inet_ntoa(client_addr->sin_addr));
 24             close(client_fd);
 25             break;
 26         }
 27         buf[read_size] = '\0';
 28         printf("client %s say:%s!\n", inet_ntoa(client_addr->sin_addr), buf);
 29         write(client_fd, buf, strlen(buf));
        }
 31     return;
 32 }
 33 
 34 void CreateWorker(int client_fd, struct sockaddr_in *client_addr)
 35 {
 36     pid_t pid = fork();
 37     if( pid < 0 ){
 38         perror("fork");
 39         return;
 40     }else if( pid == 0 ){
 41         //child
 42         if( fork() == 0 ){
 43             //孙子进程
 44             ProcessRequest(client_fd, client_addr);
 45         }
 46         exit(0);
 47     }else{
 48         //father
 49         close(client_fd);
 50         waitpid(pid, NULL, 0);
 51     }
 52 
 53 }
 54
 55
 56 void Usage()
 57 {
 58     printf("Usage: ./server [ip] [port] \n");
 59 }
 60 
 61 
 62 int main(int argc ,char *argv[])
 63 {
 64     if( argc != 3 ){
 65         Usage();
 66         return 1;
 67     }
 68 
 69     struct sockaddr_in addr;
 70     addr.sin_family = AF_INET;
 71     addr.sin_port = htons(atoi(argv[2]));
 72     addr.sin_addr.s_addr = inet_addr(argv[1]);
 73 
 74     int fd = socket(AF_INET, SOCK_STREAM, 0);
 75     if(fd < 0){
 76         perror("socket");
 77         return 2;
 78     }
 79 
 80     int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
 81     if( ret < 0 ){
 82         perror("bind");
 83         return 3;
 84     }
 85 
 86     ret = listen(fd, 10);
 87     if( ret < 0 ){
 88         perror("listen");
 89         return 4;
 90     }
 91 
 92     for(;;){
 93         struct sockaddr_in client_addr;
 94         socklen_t len = sizeof(client_addr);
 95         int client_fd = accept(fd, (struct sockaddr*)&client_addr, &len);
 96         if( client_fd < 0 ){
 97             perror("accept");
 98             continue;
 99         }
100         CreateWorker(client_fd, &client_addr);
101 
102     }
103     return 0;
104 }

多线程版本

扫描二维码关注公众号,回复: 2377690 查看本文章
 2 #include <pthread.h>
  3 #include <stdio.h>
  4 #include <stdlib.h>
  5 #include <sys/socket.h>
  6 #include <sys/types.h>
  7 #include <netinet/in.h>
  8 #include <arpa/inet.h>
  9 #include <sys/wait.h>
 10 #include <string.h>
 11 #include <unistd.h>
 12 
 13 
 14 void ProcessRequest(int client_fd, struct sockaddr_in *client_addr)
 15 {
 16     char buf[1024];
 17     for(;;){
 18         ssize_t read_size = read(client_fd, buf, sizeof(buf));
 19         if(read_size < 0){
 20             perror("read");
 21             continue;
 22         }
 23         if( read_size == 0 ){
 24             printf("client: %s say bye!\n", inet_ntoa(client_addr->sin_addr));
 25             close(client_fd);
 26             break;
 27         }
 28         buf[read_size] = '\0';
 29         printf("client %s say:%s!\n", inet_ntoa(client_addr->sin_addr), buf);
 30         write(client_fd, buf, strlen(buf));
 31     }
 32 }
 33 
 34 typedef struct Arg{
 35     int fd;
 36     struct sockaddr_in addr;
 37 }Arg;
 38 
 39 void CreateWorker(void *ptr)
 40 {
 41     Arg *arg = (Arg*)ptr;
 42     ProcessRequest(arg->fd, &arg->addr);
 43     free(arg);
 44     return NULL;
 45 }
 46 
 47 void Usage()
 48 {
 49     printf("Usage: ./server [ip] [port] \n");
 50 }
 51 
 52 
 53 int main(int argc ,char *argv[])
 54 {
 55     if( argc != 3 ){
 56         Usage();
 57         return 1;
 58     }
 59 
 60     struct sockaddr_in addr;
 61     addr.sin_family = AF_INET;
 62     addr.sin_port = htons(atoi(argv[2]));
 63     addr.sin_addr.s_addr = inet_addr(argv[1]);
 64 
 65     int fd = socket(AF_INET, SOCK_STREAM, 0);
 66     if(fd < 0){
 67         perror("socket");
 68         return 2;
 69     }
 70 
 71     int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
 72     if( ret < 0 ){
 73         perror("bind");
 74         return 3;
 75     }
 76 
 77     ret = listen(fd, 10);
 78     if( ret < 0 ){
 79         perror("listen");
 80         return 4;
 81     }
 82 
 83     for(;;){
 84         struct sockaddr_in client_addr;
 85         socklen_t len = sizeof(client_addr);
 86         int client_fd = accept(fd, (struct sockaddr*)&client_addr, &len);
 87         if( client_fd < 0 ){
 88             perror("accept");
 89             continue;
 90         }
 91         pthread_t tid = 0;
 92         Arg *arg = (Arg*)malloc(sizeof(Arg));
 93         arg->fd = client_fd;
 94         arg->addr = client_addr;;
 95         pthread_create(&tid, NULL, CreateWorker, (void*)arg);
 96         pthread_detach(tid);
 97 
 98     }
 99     return 0;
100 }

猜你喜欢

转载自blog.csdn.net/ijn842/article/details/81115088