您的位置:首页 > 运维架构 > Linux

linux Socket编程实例

2016-05-09 17:34 543 查看
转自:http://blog.csdn.net/hguisu/article/details/7445768/


7. Socket编程实例

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

[cpp] view
plain copy

 print?





/* File Name: server.c */  

#include<stdio.h>  

#include<stdlib.h>  

#include<string.h>  

#include<errno.h>  

#include<sys/types.h>  

#include<sys/socket.h>  

#include<netinet/in.h>  

#define DEFAULT_PORT 8000  

#define MAXLINE 4096  

int main(int argc, char** argv)  

{  

    int    socket_fd, connect_fd;  

    struct sockaddr_in     servaddr;  

    char    buff[4096];  

    int     n;  

    //初始化Socket  

    if( (socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){  

    printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);  

    exit(0);  

    }  

    //初始化  

    memset(&servaddr, 0, sizeof(servaddr));  

    servaddr.sin_family = AF_INET;  

    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//IP地址设置成INADDR_ANY,让系统自动获取本机的IP地址。  

    servaddr.sin_port = htons(DEFAULT_PORT);//设置的端口为DEFAULT_PORT  

  

    //将本地地址绑定到所创建的套接字上  

    if( bind(socket_fd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){  

    printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);  

    exit(0);  

    }  

    //开始监听是否有客户端连接  

    if( listen(socket_fd, 10) == -1){  

    printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);  

    exit(0);  

    }  

    printf("======waiting for client's request======\n");  

    while(1){  

//阻塞直到有客户端连接,不然多浪费CPU资源。  

        if( (connect_fd = accept(socket_fd, (struct sockaddr*)NULL, NULL)) == -1){  

        printf("accept socket error: %s(errno: %d)",strerror(errno),errno);  

        continue;  

    }  

//接受客户端传过来的数据  

    n = recv(connect_fd, buff, MAXLINE, 0);  

//向客户端发送回应数据  

    if(!fork()){ /*紫禁城*/  

        if(send(connect_fd, "Hello,you are connected!\n", 26,0) == -1)  

        perror("send error");  

        close(connect_fd);  

        exit(0);  

    }  

    buff
 = '\0';  

    printf("recv msg from client: %s\n", buff);  

    close(connect_fd);  

    }  

    close(socket_fd);  

}  

客户端:

[cpp] view
plain copy

 print?





/* File Name: client.c */  

  

#include<stdio.h>  

#include<stdlib.h>  

#include<string.h>  

#include<errno.h>  

#include<sys/types.h>  

#include<sys/socket.h>  

#include<netinet/in.h>  

  

#define MAXLINE 4096  

  

  

int main(int argc, char** argv)  

{  

    int    sockfd, n,rec_len;  

    char    recvline[4096], sendline[4096];  

    char    buf[MAXLINE];  

    struct sockaddr_in    servaddr;  

  

  

    if( argc != 2){  

    printf("usage: ./client <ipaddress>\n");  

    exit(0);  

    }  

  

  

    if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){  

    printf("create socket error: %s(errno: %d)\n", strerror(errno),errno);  

    exit(0);  

    }  

  

  

    memset(&servaddr, 0, sizeof(servaddr));  

    servaddr.sin_family = AF_INET;  

    servaddr.sin_port = htons(8000);  

    if( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){  

    printf("inet_pton error for %s\n",argv[1]);  

    exit(0);  

    }  

  

  

    if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){  

    printf("connect error: %s(errno: %d)\n",strerror(errno),errno);  

    exit(0);  

    }  

  

  

    printf("send msg to server: \n");  

    fgets(sendline, 4096, stdin);  

    if( send(sockfd, sendline, strlen(sendline), 0) < 0)  

    {  

    printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);  

    exit(0);  

    }  

    if((rec_len = recv(sockfd, buf, MAXLINE,0)) == -1) {  

       perror("recv error");  

       exit(1);  

    }  

    buf[rec_len]  = '\0';  

    printf("Received : %s ",buf);  

    close(sockfd);  

    exit(0);  

}  

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

[cpp] view
plain copy

 print?





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 

等待输入消息



发送一条消息,输入:c++



此时服务器端看到:



客户端收到消息:



其实可以不用client,可以使用telnet来测试:

telnet 127.0.0.1 8000



注意:

在ubuntu 编译源代码的时候,头文件types.h可能找不到。

使用dpkg -L libc6-dev | grep types.h 查看。

如果没有,可以使用

apt-get install libc6-dev安装。

如果有了,但不在/usr/include/sys/目录下,手动把这个文件添加到这个目录下就可以了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: