网络套接字socket(tcp、server、client)

在实现套接字网络通信之前,先来了解一下概念:

socket

socket这个词在TCP/IP协议中,“IP地址+TCP或UDP端口号”唯一标识网
络通讯中的一个进程,“IP地址+端口号”就称为socket。

网络字节序

  网络通信的时候必须知道端口号,如果发送端是大端字节序,接收端是小端字节序,那么最后看到的端口号就是不正确的端口号,所以,我们必须将端口号在发送端和接收端之间转换成统一的字节序形式,TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节

相关端口
  struct sockaddr_in
  {
     __SOCKADDR_COMMON (sin_);     //协议类型
     in_port_t sin_port;         // Port number
     struct in_addr sin_addr;        // Internet address  

     /* Pad to size of `struct sockaddr'.  */
     unsigned char sin_zero[sizeof (struct sockaddr) -
                __SOCKADDR_COMMON_SIZE -
                sizeof (in_port_t) -
                sizeof (struct in_addr)];
   };

socket:申请文件描述符

 int socket(int domain, int type, int protocol);
 //protocol参数: 与特定的地址家族相关的协议,TCP协议一般为IPPROTO_TCP。也可以写0,那么系统会根据地址格式和套接字类别,自动选择一个适合的协议。

listen:使上面申请到的文件描述符进入监听状态

 int listen(int sockfd, int backlog);   //backlog连接队列长度

bind:绑定本机的信息,包括,IP地址类型,IP地址,端口号

int bind(int sockfd, cinst struct sockaddr *affr, 
        socklen_t addrlen);

accept:接受监听套接字,成功返回一个文件描述符(真正用于通信的套接字)

int accept(int sockfd, struct sockaddr *addr, 
           sochlen_t *addrlen);
下面来完成一个tcp的客户端和用户端的编写
//server.c
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
int StartUp(int port,const char* ip)
{
    int ListenSock = socket(AF_INET,SOCK_STREAM,0);
    if(ListenSock < 0)
    {
        perror("socket");
        exit(1);
    }
    struct sockaddr_in local;
    local.sin_family = AF_INET;
    local.sin_port = htons(port);
    local.sin_addr.s_addr = inet_addr(ip);
    if(bind(ListenSock,(struct sockaddr*)&local,sizeof(local)) < 0)
    {
        perror("bind");
        exit(2);
    }
    if(listen(ListenSock,5) < 0)
    {
        perror("listen");
        exit(3); 
    }
    return ListenSock;
}

int main(int argc,const char* argv[])
{
    if(argc != 3)
    {
        printf("input error\n");
        return 1;
    }
    int len;
    int listenSock = StartUp(atoi(argv[2]),argv[1]);
    struct sockaddr_in client;
    while(1)
    {
        int sock = accept(listenSock,(struct sockaddr*)&client,&len);//获取客户机的信息
        if(sock < 0)
        {
            perror("accept");
            continue;
        }
        printf("get a client,ip is %s,port is %d\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));
        char buf[1024];
        while(1)
        {
            ssize_t s = read(sock,buf,sizeof(buf)-1);//服务器进行读数据
            if(s > 0)
            {
                buf[s] = 0;
                printf("client# %s\n",buf);
            }
            else
            {
                //数据已经读完了,客户端不发送数据了
                printf("client is quit!\n");
            }
        }
        close(sock);
    }
    return 0;
}
//client.c
#include<stdio.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<unistd.h>
#include<arpa/inet.h>

int main(int argc,const char* argv[])
{
    int sock = socket(AF_INET,SOCK_STREAM,0);
    if(sock < 0)
    {
        perror("socket");
        return 1;
    }
    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_port = htons(atoi(argv[2]));
    server.sin_addr.s_addr = inet_addr(argv[1]);
    if(connect(sock,(struct sockaddr*)&server,sizeof(server)) < 0)
    {
        perror("connect");
        return 2;
    }
    char buf[1024];
    while(1)
    {
        printf("send# ");
        fflush(stdout);
        //从标准输入读数据,读到buf中,然后从buf写到管道
        ssize_t s = read(0,buf,sizeof(buf)-1);
        if(s < 0)
        {           
            perror("read");
            return 3;
        }       
        buf[s-1] = 0;
        write(sock,buf,s);
    }
    close(sock);
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值