相关函数
int socket(int domain,int type,int protocol);
参数:
 domain:
 AF_INET
 AF_INET6
 AF_UNIX,AF_LOCAL
 AF_NETLINK
 AF_PACKET
 type:
 SOCK_STREAM: 流式套接字,唯一对应于TCP
 SOCK_DGRAM:数据报套接字,唯一对应着UDP
 SOCK_RAW:原始套接字
 protocol:
 一般填0,原始套接字编程时需填充
 返回值
 成功返回文件描述符
 出错返回-1
 如果是IPV6编程,要使用struct sockddr_in6结构体(man 7 IPV6),通常使用struct sockaddr_storage来编程。
int bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen)
参数
 sockfd:通过socket()函数拿到的fd
 addr:采用struct sockaddr的结构体地址,通用结构体
 struct sockaddr{
 sa_family_t sa_family;
 char sa_data[4];
 }
 struct sockaddr_in{ 基于Internel通信结构体
 as_family_t sin_family;
 in_port_t sin_port;
 struct in_addr sin_addr;
 sin_zero , //填充字节,需清零
 }
 struct in_addr{
 uint32_t s_addr;
 }
 addrlen:地址长度
int listen(int sockfd,int backlog);
参数:
 sockfd: 通过socket()函数拿到的fd;
 backLog:同时允许几路客户端和服务器进行正在连接的过程(正在三次握手),一般填5。
返回值:
 成功返回0
 出错返回-1
 listen(fd,5);//表示系统允许11(2*5+1)个客户端同时进行三次握手
阻塞等待客户端连接请求
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数
 sockfd:经过前面socket()创建并通过bind(),listen()设置过的fd
 addr:指向存放地址信息的结构体的首地址
 获取客服端IP地址和端口号
 addrlen:存放地址信息的结构体的大小
 返回值
 成功,返回返回已经建立连接的新的newfd
 出错,返回-1
int connect (int sockfd, struct sockaddr * serv_addr, int addrlen)
参数:
 sockfd
文章目录
- TCP服务端实现步骤:
- TCP服务端代码
 
- TCP 客户端实现步骤:
- TCP 客户端代码
- 执行结果
 
 
TCP服务端实现步骤:
1.socket函数创建一个(监听)套接字
 2.bind函数给套接字绑定地址(IP + Port)。即给套接字提高网络连接路口
 3.listen函数将套接字设置为监听状态,相当于将手机设置为待机状态。调用listen 函数实现。
 4.accept函数阻塞接收客户端连接。
 5.收发数据,调用 send/write 和 recv/read 函数实现。
 6.调用 close 函数实现关闭客服端连接。
TCP服务端代码
tcp_ser.c
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#define SERV_PORT 8888
#define SERV_IP_ADDR "192.168.11.128"
#define BACKLOG 5
#define BUFSIZE 1024
#define QUIT_STR "QUIT"
int main()
{
        int sockfd;
    //1.创建套接字
        sockfd=socket(AF_INET,SOCK_STREAM,0);
        if(sockfd<0)
        {
                perror("socket");
                exit(1);
        }
    //2.给套接字绑定地址
        struct sockaddr_in myaddr;
        //清零myaddr结构体里的数据
        bzero(&myaddr,sizeof(myaddr));
        //初始化myaddr结构体
        myaddr.sin_family=AF_INET;   //协议簇
        myaddr.sin_port=htons(SERV_PORT); //指定端口,主机字节序转换为网络字节序
        myaddr.sin_addr.s_addr=inet_addr(SERV_IP_ADDR);//指定IP地址,将字符串转为无符号整型
        //inet_pton(AF_INET,SERV_IP_ADDR,(void *)myaddr.sin_addr_s_addr);
        int ret=bind(sockfd,(struct sockaddr *)&myaddr,sizeof(myaddr));
        if(ret ==-1)
        {
                perror("bind");
                exit(2);
        }
   //3.使套接字能够监听,能够被其他客服端连接
        int res_lis=listen(sockfd,BACKLOG);
 if(res_lis==-1)//表示系统允许11(2*5+1)个客户端同时进行三次握手
        {
                perror("listen");
                //exit(3);
        }
        char buff[BUFSIZE];
   //4.阻塞等待接受客服端连接
        struct sockaddr_in saddr;
        bzero(&saddr,sizeof(saddr));
        //等待连接
        socklen_t length = sizeof(saddr);
        int newfd=accept(sockfd,(struct sockaddr *)&saddr,&length);
        if(newfd<0)
        {
                perror("accept");
                exit(5);
        }
        while(1)
        {
                        memset((void *)buff,0,1024);
                        int ret2=read(newfd,buff,sizeof(buff));
                        if(ret2<=0)
                        {
                                break;
                        }
                         /*int ret2=recv(newfd,buff,BUFSIZE-1,0);
                         if(ret2==0)
                        {       
              break;
                        }*/
                         printf("receive data is %s\n",buff);
                //判断是否接受到的数据是不是QUIT_STR,是的话,就退出此次循环
                        if(!strncasecmp(buff,QUIT_STR,strlen(QUIT_STR)))
                        {
                                printf("client is exiting\n");
                                break;
                        }
        }
        close(newfd);
        close(sockfd);
        return 0;
}
                                                                                                                                                                                          
TCP 客户端实现步骤:
1.socket函数创建一个套接字。
 2.(可以绑定也可以不绑定)bind函数给套接字绑定地址,如果没有绑定,系统将自动给套
 接字分配地址。
 3.connect函数连接服务器。
 4.收发数据,调用 send/write 和 recv/read 函数实现。
 5.close函数断开连接
TCP 客户端代码
tcp_cli.c
#include <stdio.h>
#include <arpa/inet.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <stdlib.h>
#define  SERV_PROT 8888
#define  SERV_IP_ADDR "192.168.11.128"
#define  BUFSZIE 1024
#define  QUIT_STR "QUIT"
int main()
{
        int sockfd;
        //1.创建一个套接字
        sockfd=socket(AF_INET,SOCK_STREAM,0);
        //2.不调bind函数来给套接字绑定地址,由系统自动分配
        //3.连接服务器件
        struct sockaddr_in saddr;
        saddr.sin_family=AF_INET;
        saddr.sin_port=htons(SERV_PROT);
        saddr.sin_addr.s_addr=inet_addr(SERV_IP_ADDR);
        if(connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr)) == -1)
        {
                perror("connect");
                exit(1);
        }
        char buffer[1024];
        while(1)
        {
                memset(buffer,0,1024);
                if(fgets(buffer,1024,stdin)==NULL)
                {
                        continue;
                }
                send(sockfd,buffer,sizeof(buffer),0);
                if(!strncasecmp(buffer,QUIT_STR,strlen(QUIT_STR)))
                {
                        break;
                 }
        }
        close(sockfd);
        return 0;
}
                                                       
执行结果

 客户端向服务端发送数据,当发送数据为quit时,就服务端和客服端的连接。

![[Power Query] 日期和时间处理](https://img-blog.csdnimg.cn/e32e5f205503482ebb264c2715548aa1.png)





![[附源码]Python计算机毕业设计Django考试系统](https://img-blog.csdnimg.cn/a37ed9a3197a4395b6724029aa19f0d6.png)











