Linux下系统调用编程socket(2)

来源:互联网 发布:矩阵的秩代表什么 编辑:程序博客网 时间:2024/05/22 02:17

7. Socket编程实例

服务器端:一直监听本机的8000号端口,如果收到连接请求,将接收请求并接收客户端发来的消息,并向客户端返回消息。

[cpp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. /* File Name: server.c */  
  2. #include<stdio.h>  
  3. #include<stdlib.h>  
  4. #include<string.h>  
  5. #include<errno.h>  
  6. #include<sys/types.h>  
  7. #include<sys/socket.h>  
  8. #include<netinet/in.h>  
  9. #define DEFAULT_PORT 8000  
  10. #define MAXLINE 4096  
  11. int main(int argc, char** argv)  
  12. {  
  13.     int    socket_fd, connect_fd;  
  14.     struct sockaddr_in     servaddr;  
  15.     char    buff[4096];  
  16.     int     n;  
  17.     //初始化Socket  
  18.     if( (socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){  
  19.     printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);  
  20.     exit(0);  
  21.     }  
  22.     //初始化  
  23.     memset(&servaddr, 0, sizeof(servaddr));  
  24.     servaddr.sin_family = AF_INET;  
  25.     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//IP地址设置成INADDR_ANY,让系统自动获取本机的IP地址。  
  26.     servaddr.sin_port = htons(DEFAULT_PORT);//设置的端口为DEFAULT_PORT  
  27.   
  28.     //将本地地址绑定到所创建的套接字上  
  29.     if( bind(socket_fd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){  
  30.     printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);  
  31.     exit(0);  
  32.     }  
  33.     //开始监听是否有客户端连接  
  34.     if( listen(socket_fd, 10) == -1){  
  35.     printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);  
  36.     exit(0);  
  37.     }  
  38.     printf("======waiting for client's request======\n");  
  39.     while(1){  
  40. //阻塞直到有客户端连接,不然多浪费CPU资源。  
  41.         if( (connect_fd = accept(socket_fd, (struct sockaddr*)NULL, NULL)) == -1){  
  42.         printf("accept socket error: %s(errno: %d)",strerror(errno),errno);  
  43.         continue;  
  44.     }  
  45. //接受客户端传过来的数据  
  46.     n = recv(connect_fd, buff, MAXLINE, 0);  
  47. //向客户端发送回应数据  
  48.     if(!fork()){ /*紫禁城*/  
  49.         if(send(connect_fd, "Hello,you are connected!\n", 26,0) == -1)  
  50.         perror("send error");  
  51.         close(connect_fd);  
  52.         exit(0);  
  53.     }  
  54.     buff[n] = '\0';  
  55.     printf("recv msg from client: %s\n", buff);  
  56.     close(connect_fd);  
  57.     }  
  58.     close(socket_fd);  
  59. }  

客户端:

[cpp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. /* File Name: client.c */  
  2.   
  3. #include<stdio.h>  
  4. #include<stdlib.h>  
  5. #include<string.h>  
  6. #include<errno.h>  
  7. #include<sys/types.h>  
  8. #include<sys/socket.h>  
  9. #include<netinet/in.h>  
  10.   
  11. #define MAXLINE 4096  
  12.   
  13.   
  14. int main(int argc, char** argv)  
  15. {  
  16.     int    sockfd, n,rec_len;  
  17.     char    recvline[4096], sendline[4096];  
  18.     char    buf[MAXLINE];  
  19.     struct sockaddr_in    servaddr;  
  20.   
  21.   
  22.     if( argc != 2){  
  23.     printf("usage: ./client <ipaddress>\n");  
  24.     exit(0);  
  25.     }  
  26.   
  27.   
  28.     if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){  
  29.     printf("create socket error: %s(errno: %d)\n", strerror(errno),errno);  
  30.     exit(0);  
  31.     }  
  32.   
  33.   
  34.     memset(&servaddr, 0, sizeof(servaddr));  
  35.     servaddr.sin_family = AF_INET;  
  36.     servaddr.sin_port = htons(8000);  
  37.     if( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){  
  38.     printf("inet_pton error for %s\n",argv[1]);  
  39.     exit(0);  
  40.     }  
  41.   
  42.   
  43.     if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){  
  44.     printf("connect error: %s(errno: %d)\n",strerror(errno),errno);  
  45.     exit(0);  
  46.     }  
  47.   
  48.   
  49.     printf("send msg to server: \n");  
  50.     fgets(sendline, 4096, stdin);  
  51.     if( send(sockfd, sendline, strlen(sendline), 0) < 0)  
  52.     {  
  53.     printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);  
  54.     exit(0);  
  55.     }  
  56.     if((rec_len = recv(sockfd, buf, MAXLINE,0)) == -1) {  
  57.        perror("recv error");  
  58.        exit(1);  
  59.     }  
  60.     buf[rec_len]  = '\0';  
  61.     printf("Received : %s ",buf);  
  62.     close(sockfd);  
  63.     exit(0);  
  64. }  

inet_pton 是Linux下IP地址转换函数,可以在将IP地址在“点分十进制”和“整数”之间转换 ,是inet_addr的扩展。

[cpp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. int inet_pton(int af, const char *src, void *dst);//转换字符串到网络地址:  
第一个参数af是地址族,转换后存在dst中
    af = AF_INET:src为指向字符型的地址,即ASCII的地址的首地址(ddd.ddd.ddd.ddd格式的),函数将该地址转换为in_addr的结构体,并复制在*dst中
  af =AF_INET6:src为指向IPV6的地址,函数将该地址转换为in6_addr的结构体,并复制在*dst中
如果函数出错将返回一个负值,并将errno设置为EAFNOSUPPORT,如果参数af指定的地址族和src格式不对,函数将返回0。

测试:

编译server.c

gcc -o server server.c

启动进程:

./server

显示结果:

======waiting for client's request======

并等待客户端连接。

编译 client.c

gcc -o client server.c

客户端去连接server:

./client 127.0.0.1 

等待输入消息


0 0
原创粉丝点击