苏嵌实训——day17(下)

简介: 苏嵌实训——day17(下)

2.7.3 listen


头文件:#include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>
原型:int listen(int sockfd, int backlog);
功能:将套接字设置为被动监听状态
参数:
    sockfd:文件描述符,socket的返回值
    backlog:允许同时连接的客户端的个数,一般设置为5,10
返回值:
成功:0
失败:-1


2.7.4 accept


头文件:#include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>
原型:int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:阻塞等待客户端的连接
参数:
    sockfd:文件描述符,socket的返回值
    addr:被填充的网络信息结构体,如果由客户端连接服务器,服务器可以通过这个参数获取客户端的信息
    addrlen:addr的大小
返回值:
成功:返回文件描述符
失败:-1


2.7.5 connect


头文件:#include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>
原型:int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
功能:给服务器发送连接请求
参数:
    sockfd:文件描述符,socket的返回值
    addr:要连接的服务器的网络信息结构体,需要客户端自己填充
    addrlen:addr的大小
返回值:
成功:返回0
失败:-1


2.8 TCP服务器


#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include<arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int main(int argc, char const *argv[])
{
    //创建套接字
    int sockfd = socket(AF_INET,SOCK_STREAM,0);  //IPV4协议,流式套接字,具体的协议类型
    if(-1 == sockfd)
    {
        perror("socket");
        return -1;
    }
    struct sockaddr_in server_addr;   //保存服务器的信息
    memset(&server_addr,0,sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8000);
    server_addr.sin_addr.s_addr = inet_addr("192.168.98.147");
    //绑定信息
    int ret = bind(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr));
    if(-1 == ret)
    {
        perror("bind");
        return -1;
    }
    //设置监听队列
    ret = listen(sockfd,10);
    if(-1 == ret)
    {
        perror("listen");
        return -1;
    }
    printf("等待客户端进行连接...、\n");
    struct sockaddr_in Client_addr;    //用于保存客户端的信息
    int length = sizeof(Client_addr);
    int fd = accept(sockfd,(struct sockaddr *)&Client_addr,&length);
    if(-1 == fd)
    {
        perror("accept");
        return -1;
    }
    printf("接收客户端的连接 %d\n",fd);
    char buf[32] = {0};
    while(1)
    {
        ret = recv(fd,buf,sizeof(buf),0);
        if(-1 == ret)
        {
            perror("recv");
            return -1;
        }
        if(strcmp(buf,"bye") == 0)
        {
            break;
        }
        printf("%s\n",buf);
        memset(buf,0 ,sizeof(buf));
    }
    close(fd);
    close(sockfd); 
    return 0;
}


2.9 TCP客户端


#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include<arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
    //创建套接字
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd == -1)
    {
        perror("socket");
        return -1;
    }
    //向服务器发起连接
    struct sockaddr_in server_addr;   //保存服务器的信息
    memset(&server_addr,0,sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8000);
    server_addr.sin_addr.s_addr = inet_addr("192.168.98.147");
    int ret = connect(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr));
    if(-1 == ret)
    {
        perror("connect");
        return -1;
    }
    char buf[32] = {0};
    while(1)
    {
        scanf("%s",buf);
        ret = send(sockfd,buf,strlen(buf),0);
        if(-1 == ret)
        {
            perror("send");
            return -1;
        }
        if(strcmp(buf,"bye") == 0)
        {
            break;
        }
        memset(buf,0,sizeof(buf));
    }
    close(sockfd);
    return 0;
}


2.10 TCP并发服务器


#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include<arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <pthread.h>
void * ClientHandler(void *arg)
{
    int ret;
    int fd = *(int *)arg;
    char buf[32] = {0};
    pthread_detach(pthread_self());    //线程结束,自动释放资源
    while(1)
    {
        ret = recv(fd,buf,sizeof(buf),0);
        if(-1 == ret)
        {
            perror("recv");
            return (void *)-1;
        }
        else if(0 == ret)
        {
            break;   //客户端异常退出
        }
        if(strcmp(buf,"bye") == 0)
        {
            break;
        }
        printf("接收%d客户端 %s\n",fd,buf);
        memset(buf,0 ,sizeof(buf));
    }
    printf("%d 客户端退出!\n",fd);
    close(fd);
}
int main(int argc, char const *argv[])
{
    //创建套接字
    int sockfd = socket(AF_INET,SOCK_STREAM,0);  //IPV4协议,流式套接字,具体的协议类型
    if(-1 == sockfd)
    {
        perror("socket");
        return -1;
    }
    struct sockaddr_in server_addr;   //保存服务器的信息
    memset(&server_addr,0,sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8000);
    server_addr.sin_addr.s_addr = inet_addr("192.168.98.147");
    //绑定信息
    int ret = bind(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr));
    if(-1 == ret)
    {
        perror("bind");
        return -1;
    }
    //设置监听队列
    ret = listen(sockfd,10);
    if(-1 == ret)
    {
        perror("listen");
        return -1;
    }
    printf("等待客户端进行连接...、\n");
    struct sockaddr_in Client_addr;    //用于保存客户端的信息
    int length = sizeof(Client_addr);
    while(1)
    {
        int fd = accept(sockfd,(struct sockaddr *)&Client_addr,&length);
        if(-1 == fd)
        {
            perror("accept");
            return -1;
        }
        printf("接收客户端的连接 %d\n",fd);
        //为每一个客户端创建新的线程
        pthread_t tid;
        ret = pthread_create(&tid,NULL,ClientHandler,&fd);
        if(ret != 0)
        {
            perror("pthread_create");
            return -1;
        }
    }
    close(sockfd); 
    return 0;
}


#!/bin/bash
for ((i=0;i<100;i++))
do
    ./4-Tcp客户端 &
    sleep 0.1
done


练习:实现客户端下载服务器所在目录文件

客户端发送要下载的文件名给服务器

服务器判断文件是否存在,将结果告知客户端

如果文件存在,服务器读取文件内容,并发送给客户端

客户端收到文件内容并写入指定的文件


2.11 UDP 网络编程


服务器:
  创建套接字 socket
  填充服务器网络信息结构体
  将套接字和网络信息结构体绑定bind
  进行通信 recvfrom /sendto()
客户端:
  创建套接字 socket
  填充网络信息结构体
  进行通信 recvfrom/sendto


函数接口recvfrom/sendto
------recvfrom
1.recvfrom/sendto
------recvfrom
头文件:#include <sys/types.h>
       #include <sys/socket.h>
原型:ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                        struct sockaddr *src_addr, socklen_t *addrlen);
功能:接收数据
参数:
    前四个和recv一样
    src_addr:源的地址,接收谁的数据,他的信息会自动填充到这个参数
    addrlen:src_addr的大小
返回值
    成功:实际接收的字节数
    失败: 返回-1
------sendto
头文件:#include <sys/types.h>
       #include <sys/socket.h>
原型:ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                      const struct sockaddr *dest_addr, socklen_t addrlen);
功能:接收数据
参数:
    前四个和send一样
    dest_addr:目的地址,需要自己指定
    addrlen:dest_addr的大小
返回值
    成功:发送的字节数
    失败: 返回-1
//udp服务器
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#define ERRLOG(errmsg) do{\
                            perror(errmsg);\
                            printf("%s - %s - %d\n",__FILE__,__func__,__LINE__);\
                            exit(1);\
                            }while(0)
int main(int argc, char const *argv[])
{
    int sockfd;
    //第一步:创建套接字
    if(-1 == (sockfd = socket(AF_INET,SOCK_DGRAM,0)))
    {
        ERRLOG("socket error");
    }
    struct sockaddr_in serveraddr,clientaddr;
    socklen_t addrlen = sizeof(serveraddr);
    //第二步:填充服务器网络信息结构体  
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr("192.168.98.147");
    serveraddr.sin_port = 8888;
    //第三步:将套接字与服务器网路信息结构体绑定
    int ret = bind(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
    if(ret == -1)
    {
        ERRLOG("bind");
    }
    //进行通信
    char buf[32] = {0};
    while(1)
    {
NEXT:
        if(recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&clientaddr,&addrlen) == -1)
        {
            ERRLOG("recvfrom");
        }
        if(strcmp(buf,"bye") == 0)
        {
            printf("客户端%s-%d退出了\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));
            goto NEXT;
        }
        printf("%s-%d: %s\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port),buf);
    }
    return 0;
}


//udp客户端
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#define ERRLOG(errmsg) do{\
                            perror(errmsg);\
                            printf("%s - %s - %d\n",__FILE__,__func__,__LINE__);\
                            exit(1);\
                            }while(0)
int main(int argc, char const *argv[])
{
    int sockfd;
    //第一步:创建套接字
    if(-1 == (sockfd = socket(AF_INET,SOCK_DGRAM,0)))
    {
        ERRLOG("socket error");
    }
    struct sockaddr_in serveraddr,clientaddr;
    socklen_t addrlen = sizeof(serveraddr);
    //第二步:填充服务器网络信息结构体  
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr("192.168.98.147");
    serveraddr.sin_port = 8888;
    //进行通信
    char buf[32] = {0};
    while(1)
    {
        scanf("%s",buf);
        if(sendto(sockfd,buf,32,0,(struct sockaddr *)&serveraddr,addrlen) == -1)
        {
            ERRLOG("sendto");
        }
        if(strcmp(buf,"bye") == 0)
        {
            printf("客户端退出了\n");
        }
        memset(buf,0,sizeof(buf));
    }
    return 0;
}


相关文章
|
6月前
|
SQL 前端开发 数据库
|
6月前
|
Java 关系型数据库 MySQL
|
6月前
|
算法 前端开发 Java
思途实训-day03-04
思途实训-day03-04
|
Ubuntu API 数据库
苏嵌实训——day19
苏嵌实训——day19
110 0
苏嵌实训——day19
|
消息中间件 Linux
苏嵌实训——day16(下)
苏嵌实训——day16(下)
苏嵌实训——day16(下)
|
消息中间件 存储 Linux
苏嵌实训——day16(上)
苏嵌实训——day16(上)
苏嵌实训——day16(上)
|
存储 Linux 程序员
苏嵌实训——day13(上)
苏嵌实训——day13(上)
108 0
苏嵌实训——day13(上)