TCP套接字编程入门

概述

套接字(socket)是一种通信机制,凭借这种机制,客户与服务器的通信既可以在本地单机上进行,也可以跨网络进行。

在这里插入图片描述
图:基本的TCP客户/服务器应用程序的套接字函数

图中展示了一对TCP客户与服务器进程之间进行通信时调用套接字函数的交互情况。服务器首先启动,然后监听客户的连接。稍后客户试图连接服务器,客户连接成功后,客户给服务器发送请求,服务器处理请求,并且返回给客户一个响应。这个过程一直持续下去,直到客户关闭客户端的连接,接着服务器也关闭相应的服务器端的连接,接着服务器继续等待新的客户连接。

如何编写TCP套接字程序

编写 TCP套接字程序,涉及具体的步骤:

  • 创建套接字
  • 命名套接字
  • 创建套接字队列
  • 服务器接受客户连接
  • 客户请求连接服务器
  • 发送和接收消息
  • 关闭套接字

创建套接字

可以使用系统调用socket来创建一个套接字并返回该套接字的文件描述符。

#include <sys/socket.h>
int socket(int domain, int type, int protocol);

创建的套接字是一条通信线路的一个端点。

domain
domain参数指定哪种协议族,常见的协议族包括 AF_UNIX 和 AF_INET。AF_UNIX 用于通过文件系统实现的本地套接字(类似于pipe管道),AF_INET 用于网络套接字。

type
type参数指定这个套接字的通信类型,取值包括 SOCK_STREAM 和 SOCK_DGRAM。
SOCK_STREAM 即流套接字,基于 TCP,提供可靠,有序的服务。
SOCK_DGRAM 即数据报套接字,基于 UDP,提供不可靠,无序的服务。SOCK_STREAM 类型的套接字为本文讲述的重点。

protocol
protocol允许为套接字指定一种协议。对于 AF_UNIX 和 AF_INET,我们使用默认值即可。

以下代码创建一个 TCP套接字,domain使用 AF_INET,type 使用 SOCK_STREAM,protocol 协议使用默认的 0 值。

#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv)
{
   
    // 创建TCP套接字
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0) {
   
        perror("cannot create socket");
        return 0;
    }
    printf("created socket, fd: %d\n", fd);
    exit(0);
}

命名套接字

要想让创建的套接字可以被其他进程使用,那必须给该套接字命名。对套接字命名的意思是指将该套接字关联一个IP地址和端口号,可以使用系统调用bind来实现命名套接字。

#include <sys/socket.h>
int bind(int socket, const struct sockaddr *address, size_t address_len);

bind系统调用把参数address中的地址分配给与文件描述符socket关联的套接字,地址结构的长度由参数address_len传递。

每种套接字域都有其自己的格式,对于 AF_INET 域来说,套接字地址由结构 socket_in来指定,它至少包含以下几个成员:

struct sockaddr_in {
   
    short int sin_family;         // AF_INET
    unsigned short int sin_port;  // 端口号
    struct in_addr  sin_addr;     // IP地址
};

成员sin_port表示套接字的端口号。对于客户套接字,我们一般不需要指定套接字的端口号,而对于服务器套接字,我们需要指定套接字的端口号以便让客户正确向服务器发送数据。如果不需要指定端口号,可以将sin_port的值赋为0。

成员sin_addr表示套接字的地址,即机器的IP地址。如果我们没特别为套接字绑定IP地址,操作系统会为我们选择一个机器IP地址,这时sin_addr使用地址0.0.0.0,使用INADDR_ANY来表示这个地址常量。

对一个套接字进行命名的示例代码如下,该代码创建一个TCP套接字,并监听机器的6240端口。

#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>

int main(int argc, char **argv)
{
   
    // 创建套接字
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0) {
   
        perror("cannot create socket");
        return 0;
    }
    printf("created socket, fd: %d\n", fd);

    // 命名套接字
    struct sockaddr_in myaddr;
    memset
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值