一个简单的TCP编程示例

服务器端的代码如下所示。
  1 #include 
  2 #include 
  3 #include 
  4 #include 
  5 #include 
  6 #include 
  7 
  8 #define N 128
  9 #define errlog(errmsg) do{perror(errmsg);\
 10                           printf("---%s---%s---%d---\n",\
 11                                   __FILE__, __func__, __LINE__);\
 12                           return -1;\
 13                          }while(0)
 14 int main(int argc, const char *argv[])
 15 {
 16     int sockfd, acceptfd;
 17 
 18     struct sockaddr_in serveraddr, clientaddr;
 19     socklen_t addrlen = sizeof(serveraddr);
 20     char buf[N] = "";
 21 
 22     bzero(&serveraddr, addrlen);
 23     bzero(&clientaddr, addrlen);
 24 
 25     /*提示程序需要命令行传参*/
 26     if(argc < 3){
 27         fprintf(stderr, "Usage: %s ip port\n", argv[0]);
 28         return -1;
 29     }
 30 
 31     /*创建套接字*/
 32     if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
 33         errlog("socket error");
 34     }
 35 
 36     /*填充网络信息结构体
 37      *inet_addr:将点分十进制地址转换为网络字节序的整型数据
 38      *htons:将主机字节序转换为网络字节序
 39      *atoi:将数字型字符串转化为整型数据
 40      */
 41     serveraddr.sin_family = AF_INET;
 42     serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
 43     serveraddr.sin_port = htons(atoi(argv[2]));
 44 
 45     /*将套接字与服务器网络信息结构体把绑定*/
 46     if(bind(sockfd, (struct sockaddr *)&serveraddr, addrlen) < 0){
 47         errlog("bind error");
 48     }
 49 
 50     /*将套接字设置为被动监听模式*/
 51     if(listen(sockfd, 5) < 0){
 52         errlog("listen error");
 53     }
 54 
 55     /*阻塞等待客户端的连接请求*/
 56     /*可以将后两个参数设置为NULL,表示不关注客户端的信息,不影响通信*/
 57     if((acceptfd = accept(sockfd,\
 58                     (struct sockaddr *)&clientaddr, &addrlen)) < 0){
 59         errlog("accept error");
 60     }
 61 
 62     printf("ip: %s, port: %d\n",\
 63               inet_ntoa(clientaddr.sin_addr),\
 64               ntohs(clientaddr.sin_port));
 65 
 66     ssize_t bytes;
 67 
 68     while(1){
 69         if((bytes = recv(acceptfd, buf, N, 0)) < 0){                                                                                                                                                                                                                                                                                                                                                                                       
 70             errlog("recv error");
 71         }
 72         else if(bytes == 0){
 73             errlog("no data");
 74         }
 75         else{
 76             if(strncmp(buf, "quit", 4) == 0){
 77                 printf("client quit\n");
 78                 goto err;
 79             }
 80             else{
 81                 printf("client: %s\n", buf);
 82                 strcat(buf, "-server");
 83 
 84                 if(send(acceptfd, buf, N, 0) < 0){
 85                     errlog("send error");
 86                 }
 87             }
 88         }
 89     }
 90 
 91     return 0;
 92 err:
 93     close(acceptfd);
 94     close(sockfd);
 95     return 0;
 96 }
客户端代码如下所示。
  1 #include 
  2 #include 
  3 #include 
  4 #include 
  5 #include 
  6 #include 
  7 
  8 #define N 128
  9 #define errlog(errmsg) do{perror(errmsg);\
 10                           printf("---%s---%s---%d---\n",\
 11                                   __FILE__, __func__, __LINE__);\
 12                           return -1;\
 13                          }while(0)              
14 int main(int argc, const char *argv[])
 15 {
 16     int sockfd;
 17     struct sockaddr_in serveraddr;
 18     socklen_t addrlen = sizeof(serveraddr);
 19     char buf[N] = "";   
20 
 21     /*提示程序需要命令行传参*/
 22     if(argc < 3){
 23         fprintf(stderr, "Usage: %s ip port\n", argv[0]);
 24         return -1;
 25     }
 26 
 27     /*创建套接字*/
 28     if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
 29         errlog("socket error");
 30     }
 31 
 32     /*填充网络信息结构体
 33      *inet_addr:将电分十进制地址转换为网络字节序的整型数据
 34      *htons:将主机字节序转换为网络字节序
 35      *atoi:将数字型字符串转化为整型数据
 36      */
 37     serveraddr.sin_family = AF_INET;
 38     serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
 39     serveraddr.sin_port = htons(atoi(argv[2]));                                                                                                                                      
 40 
 41 #if 0
 42     系统可以随机为客户端指定IP地址和端口号,客户端也可以自己指定
 43     struct sockaddr_in clientaddr;
 44     clientaddr.sin_family = AF_INET;
 45     clientaddr.sin_addr.s_addr = inet_addr(argv[3]);
 46     clientaddr.sin_port = htons(atoi(argv[4]));
 47 
 48     if(bind(sockfd, (struct sockaddr *)&clientaddr, addrlen) < 0){
 49         errlog("bind error");
 50     }
 51 #endif
 52 
 53     /*发送客户端连接请求*/
 54     if(connect(sockfd, (struct sockaddr *)&serveraddr, addrlen) < 0){
 55         errlog("connect error");
 56     }
57 
 58     while(1){
 59         fgets(buf, N, stdin);
 60         buf[strlen(buf) - 1] = '\0';
 61 
 62         if(send(sockfd, buf, N, 0) < 0){
 63             errlog("send error");
 64         }
 65         else{
 66             if(strncmp(buf,"quit", 4) == 0){
 67                 goto err;
 68             }
 69 
 70             if(recv(sockfd, buf, N, 0) < 0){
 71                 errlog("recv error");
 72             }
 73 
 74             printf("server: %s\n", buf);
 75         }
 76     }
 77 
 78     return 0;
 79 err:
 80     close(sockfd);
 81     return 0;
 82 }
服务器运行结果如下所示。
linux@Master:~/1000phone/net/tcp$ ./server 192.168.44.134 7777
ip: 192.168.44.134, port: 45425
client: hello world
client quit
客户端运行结果如下所示,运行客户端发起连接请求。连接成功后,发送字符串。之后接收服务器端的发送的字符串。当输入“quit”时,进程断开连接,并退出。
linux@Master:~/1000phone/net/tcp$ ./client 192.168.44.134 7777
hello world
server: hello world-server
quit      

你可能感兴趣的:(Linux系统编程)