zoukankan      html  css  js  c++  java
  • linux socket编程:简易客户端与服务端

    什么是socket?

    socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。其实socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)

    socket的作用是用于网络通讯,网络通讯一般指的是不同主机之间的进程通讯,比如我电脑上的qq和你电脑上的qq实现通讯,都是进程之间发送数据.

    在本地用pid标识一个进程,在网络中,tcp/ip协议的网络层“ip地址”可以唯一标识网络中的主机,传输层的“协议+端口”可以唯一标识主机中的应用程序(进程)。(ip地址,协议,端口)就可以标识网络的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互

    socket服务端编程基本步骤:

    1,创建套接字, 利用socket函数

    2,绑定套接字: bind

    3,监听套件字: listen

    4,accept,接收客户端的连接,3次握手就发生在这个阶段,  这个函数返回一个新的套接字

    5,处理业务

    socket客户端:

    1,创建套接字: socket

    2,连接服务端: connect

    3,处理业务

    ----------------------------------------------------------------------------------------------------------------------------------

    服务端源码:

     1 #include <stdio.h>
     2 #include <sys/types.h>
     3 #include <sys/socket.h>
     4 #include <stdlib.h>
     5 #include <string.h>
     6 #include <arpa/inet.h>
     7 #include <unistd.h>
     8 
     9 int main(int argc, char *argv[])
    10 {
    11     int sockfd = -1;
    12     int bindres = -1;
    13     int listenres = -1;
    14 
    15     sockfd = socket( AF_INET, SOCK_STREAM, 0 );
    16     if ( -1 == sockfd ) {
    17         perror( "sock created" );
    18         exit( -1 );
    19     }
    20     
    21     struct sockaddr_in server;    
    22     memset( &server, 0, sizeof( struct sockaddr_in ) );
    23     server.sin_family = AF_INET;
    24     server.sin_port = 6666;
    25     server.sin_addr.s_addr = htonl( INADDR_ANY );
    26 
    27     bindres = bind( sockfd, (struct sockaddr*)&server, sizeof( server ) );
    28     if( -1 == bindres ) {
    29         perror( "sock bind" );
    30         exit( -1 );
    31     }
    32 
    33     listenres = listen( sockfd, SOMAXCONN );
    34     if( -1 == listenres ) {
    35         perror( "sock listen" );
    36         exit( -1 );
    37     }
    38     
    39     struct sockaddr_in peerServer;
    40     int acceptfd = -1;
    41     socklen_t len = sizeof( peerServer );
    42     acceptfd = accept( sockfd, (struct sockaddr*)&peerServer, &len );
    43     if ( -1 == acceptfd ) {
    44         perror( "sock accept" );
    45         exit( -1 );
    46     }
    47 
    48     char recvBuf[1024];    
    49     while( 1 ) {
    50         memset( recvBuf, 0, sizeof( recvBuf ) );
    51         int recvBytes = read( acceptfd, recvBuf, sizeof( recvBuf ) );
    52         fputs( recvBuf, stdout );
    53         write( acceptfd,recvBuf, recvBytes );
    54     }
    55     
    56     close( sockfd );
    57     close( acceptfd );
    58 
    59     return 0;
    60 }
    View Code

    客户端源码:

     1 #include <stdio.h>
     2 #include <sys/types.h>
     3 #include <sys/socket.h>
     4 #include <stdlib.h>
     5 #include <string.h>
     6 #include <arpa/inet.h>
     7 #include <unistd.h>
     8 
     9 int main(int argc, char *argv[])
    10 {
    11     int sockfd = -1;
    12 
    13     sockfd = socket( AF_INET, SOCK_STREAM, 0 );
    14     if ( -1 == sockfd ) {
    15         perror( "sock created" );
    16         exit( -1 );
    17     }
    18     
    19     struct sockaddr_in server;    
    20     memset( &server, 0, sizeof( struct sockaddr_in ) );
    21     server.sin_family = AF_INET;
    22     server.sin_port = 6666;
    23     server.sin_addr.s_addr = inet_addr( "127.0.0.1" );
    24     
    25     int res = -1;    
    26     res = connect( sockfd, (struct sockaddr*)&server, sizeof( server ) );
    27     if( -1 == res ){
    28         perror( "sock connect" );
    29         exit( -1 );
    30     }
    31 
    32     char sendBuf[1024] = { 0 };
    33     char recvBuf[1024] = { 0 };
    34     while( fgets( sendBuf, sizeof( sendBuf ), stdin ) != NULL ) {
    35         write( sockfd, sendBuf, sizeof( sendBuf ) );
    36         read( sockfd, recvBuf, sizeof( recvBuf ) );
    37         fputs( recvBuf, stdout );
    38         memset( sendBuf, 0, sizeof( sendBuf ) );
    39         memset( recvBuf, 0, sizeof( recvBuf ) );
    40     }
    41 
    42     close( sockfd );
    43 
    44     return 0;
    45 }
    View Code

    备注:

    1、socket函数的参数:当protocol为0时,会自动选择type类型对应的默认协议

    2、将sin_addr设置为INADDR_ANY"的含义是什么?

    转换过来就是0.0.0.0,泛指本机的意思,也就是表示本机的所有IP,因为有些机子不止一块网卡,多网卡的情况下,这个就表示所有网卡ip地址的意思。 比如一台电脑有3块网卡,分别连接三个网络,那么这台电脑就有3个ip地址了,如果某个应用程序需要监听某个端口,那他要监听哪个网卡地址的端口呢? 如果绑定某个具体的ip地址,你只能监听你所设置的ip地址所在的网卡的端口,其它两块网卡无法监听端口,如果我需要三个网卡都监听,那就需要绑定3个ip,也就等于需要管理3个套接字进行数据交换,这样岂不是很繁琐? 所以出现INADDR_ANY,你只需绑定INADDR_ANY,管理一个套接字就行,不管数据是从哪个网卡过来的,只要是绑定的端口号过来的数据,都可以接收到

  • 相关阅读:
    跨DLL边界传递CRT对象的隐患(或诸如:HEAP[]: Invalid Address specified to RtlValidateHeap(#,#)问题出现的原因)
    【策略模式】不同的时间用不同的规则优先考虑策略模式
    【装饰模式】遵循开闭原则,使用一个类装饰另一个类
    【简单的工厂模式】一个简单的计算器
    【原】使用Golang语言编写echo程序
    WebBrowser或CHtmlView中轻松屏蔽脚本错误(JavaScript)
    春运买票难,是谁造成的?
    搜狗输入法使用感受
    [原]在 go/golang语言中使用 google Protocol Buffer
    防护针对SQL Server数据库的SQL注入攻击
  • 原文地址:https://www.cnblogs.com/ghostwu/p/8242052.html
Copyright © 2011-2022 走看看