服务器

**************************************************************************************************************

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>

#define PTOR 6666
#define IP      "192.168.31.162"

#define ERR_MSG(msg)  do{\
    fprintf(stderr,"__%d__\n",__LINE__);\
    perror(msg);\
}while(0)

int main(int argc, const char *argv[])
{
    //1、创建流式套接字,返回值为文件描述符
    int sfd=socket(AF_INET,SOCK_STREAM,0);
    if(sfd<0)
    {
        ERR_MSG("socket");
        return -1;
    }

//如果不加这段代码,则服务器异常退出后,会导致端口号在30s~3min内释放不出来
    //当程序结束后,想要让其他进程能够快速复用端口号,就可以使用下面的代码
    //允许端口快速被重用
    int reuse = 1;
    if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse ,sizeof(reuse)) < 0)
    {   
        ERR_MSG("setsockopt");
        return -1;                                                                                    
    }   
    printf("允许端口快速重用\n");

//2、填充地址信息结构体,真实的地址信息结构体根据地址族制定
    struct sockaddr_in sin;
    sin.sin_family =AF_INET;//必须填AF_INET;
    sin.sin_port   =htons(PTOR);//网络字节序,端口号是2字节,所以用htons将主机字节序转为网络字节序
    sin.sin_addr.s_addr   =inet_addr(IP);//本机IP
    //printf("%d:%d_,%#x\n",__LINE__,htons(PTOR),inet_addr(IP));
    //3、将地址信息结构体绑定到套接字上
    if(bind(sfd,(struct sockaddr *)&sin,sizeof(sin))<0)
    {
        ERR_MSG("bind");
        return -1;
    }
    //4、将套接字设置为被动监听状态
    if(listen(sfd,128)<0)
    {
        ERR_MSG("listen");
        return -1;
    }
    printf("服务器设置被动监听设置成功\n");

struct sockaddr_in cin;
    socklen_t  cinlen=sizeof(cin);
    //5、accept从队头获取一个客户端信息
    int newfd = accept(sfd,(struct sockaddr *)&cin,&cinlen);
    if(newfd<0)
    {
        ERR_MSG("accept");
        return -1;
    }
    printf("[%s:%d] newfd = %d 连接成功\n", \
            inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd);

//6、数据传输
    char buf[32]="";
    ssize_t res=0;
    while(1)
    {
        //接收
        bzero(buf,sizeof(buf));

res=recv(newfd,buf,sizeof(buf),0);
        if(res<0)
        {
            ERR_MSG("recv");
            return -1;
        }
        else if(0==res)
        {
            printf("newfd=%d 客户端关闭\n",newfd);
            break;
        }
        printf("res:%ld,newfd:%d,res:%s\n",res,newfd,buf);

//发送
        //将发送一个数据到用户IP
        printf("服务器发送-->\n");
        fgets(buf,sizeof(buf),stdin);
        buf[sizeof(buf)-1]=0;
        if(send(newfd,buf,sizeof(buf),0)<0)
        {
            ERR_MSG("send");
            return -1;
        }
        bzero(buf,sizeof(buf));

printf("send success\n");
    }
    close(newfd);
    close(sfd);
    return 0;
}
**************************************************************************************************************

客户端

**************************************************************************************************************

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>

#define ser_PTOR 6666
#define ser_IP      "192.168.31.162"

#define ERR_MSG(msg)  do{\
    fprintf(stderr,"__%d__\n",__LINE__);\
    perror(msg);\
}while(0)

int main(int argc, const char *argv[])
{
    //1、创建流式套接字,返回值为文件描述符
    int sfd=socket(AF_INET,SOCK_STREAM,0);
    if(sfd<0)
    {
        ERR_MSG("socket");
        return -1;
    }

//绑定客户端自身IP和端口,到对应的套接字上;——非必要绑定
    //不绑定程序运行后操作系统会自动分配一个在49152—65535之间的端口号给套接字

//填充地址信息结构体,真实地址信息结构体根据地址族来制定
    //struct sockaddr_in

//2、填充服务器的地址信息结构体,因为connect函数中要通过地址信息结构体来链接服务器
    struct sockaddr_in sin;
    sin.sin_family =AF_INET;//必须填AF_INET;
    sin.sin_port   =htons(ser_PTOR);//服务器绑定的端口
    sin.sin_addr.s_addr   =inet_addr(ser_IP);//服务器绑定的IP
    //注意,切换网络环境后IP是会发生改变的

//3、连接服务器
    if(connect(sfd,(struct sockaddr *)&sin,sizeof(sin))<0)
    {
        ERR_MSG("connect");
        return -1;
    }
    printf("connect success\n");
    struct sockaddr_in cin;
    socklen_t  cinlen=sizeof(cin);
    //6、数据传输
    char buf[32]="";
    ssize_t res=0;
    while(1)
    {
        //发送
        //将获取到的数据拼接后发送回去
        printf("请输入-->\n");
        fgets(buf,sizeof(buf),stdin);
        buf[sizeof(buf)-1]=0;
        if(send(sfd,buf,sizeof(buf),0)<0)
        {
            ERR_MSG("send");
            return -1;
        }
        bzero(buf,sizeof(buf));
        printf("send success\n");

//接收
        bzero(buf,sizeof(buf));
        res=recv(sfd,buf,sizeof(buf),0);
        if(res<0)
        {
            ERR_MSG("recv");
            return -1;
        }
        else if(0==res)
        {
            printf("sfd=%d 客户端关闭\n",sfd);
            break;
        }
        printf("res:%ld,sfd:%d,res:%s\n",res,sfd,buf);
    }
    close(sfd);
    return 0;
}

网络编程:使用tcp协议实现服务器与客户端交互相关推荐

  1. 网络编程——基于TCP协议的通讯录【课程设计】

    网络编程--基于TCP协议的通讯录[课程设计] 本文目录 网络编程--基于TCP协议的通讯录[课程设计] 一.设计题目和要求 设计目标: 课程设计系统组成及模块功能: 二.设计内容 服务端 客户端 S ...

  2. TCP协议的服务器与客户端的程序设计(代码注释超详细)

    在上篇博客中讲到了三次握手和四次挥手: Linux网络编程--TCP中的三次握手和四次挥手_神厨小福贵!的博客-CSDN博客服务器编程和客户端编程的大致流程如下:三次握手是在客户端中的connect中 ...

  3. 基于ZYNQ-7000的AI加速器设计之PS端(ARM)网络编程(TCP协议)

    前注:ARM端的TCP协议编程步骤和UDP协议编程步骤完全相同,只是在ARM端的C代码实现不同,在本次TCP协议实现过程中我们主要利用了官方提供的Demo,然后根据自己的需要加以改写,具体过程如下. ...

  4. Linux 系统应用编程——网络编程(TCP 协议三次握手过程)

    TCP(Transmission Control Protocol) 传输控制协议  TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种 ...

  5. C语言网络编程:TCP实现多线程实现多客户端

    TCP通信的编程模型如下: TCP通信是必须要有一个服务器,通过accept函数与客户端socket进行三次握手连接创建的通信描述符与客户端进行数据传输. 此时可以将accept函数的连接设置为多线程 ...

  6. step5 . day6 网络编程 基于TCP协议的多并发模式(使用多进程、多线程、select函数分别实现)...

    实现TCP服务器端多路并发的方法有①多进程②多线程③IO多路复用(select poll epoll函数) 1.多进程实现并发模式(仅在服务器端更改之前代码实现) 服务器端 #include < ...

  7. Java学习笔记53(网络编程:TCP协议案例)

    简易的案例 客户端: package demo;import java.io.IOException; import java.io.InputStream; import java.io.Outpu ...

  8. 利用TCP协议完成服务器与客户端之间文件传输

    利用TCP文件传输协议模拟与服务器的文件上传.下载操作,以及进入各种目录和列举当前目录文件状态操作.ls为查看当前目录,cd+目录名进入该目录,cd -则返回上一级目录,dow加文件名则下载文件到本地 ...

  9. C语言网络编程:多路IO select实现多客户端

    文章目录 阻塞式的服务器程序 多线程服务器程序 非阻塞式服务器程序 基于事件响应的服务器程序 事件响应服务器程序的实现`select` 阻塞式的服务器程序 我们接触过最多的最基础的网络通信模型为TCP ...

最新文章

  1. 二叉树最近公共祖先节点
  2. python爬取mysql_Python如何爬取51cto数据并存入MySQL
  3. 像素画高级教程:怎样画流动的水
  4. Android:解决Button中的文字全部大写
  5. 基于Xml 的IOC 容器-载入配置路径
  6. 7.Appium 安卓自动化(Package与Activity)
  7. C++有名管道通信简单示例
  8. 使用VSTS为ASP.NET Core构建DevOps CI/CD管道
  9. Linux复习-硬盘相关知识点
  10. G-sensor概述及常用芯片整理
  11. CAD打印 acad.ctb丢失
  12. JS逆向day01-青果教务系统登录接口
  13. 林达华——我的PhD生活
  14. 二十年间的失败软件和系统
  15. 《增长黑客》- 读书笔记(四)增长黑客循环
  16. Python学习笔记4---类和对象
  17. Python matplotlib绘图,使用鼠标滚轮放大/缩小图像
  18. python算法与程序基础题库,计算机算法与程序设计(python)MOOC章节测试答案
  19. 全国大学生电子设计竞赛(二)--电源常用技术与算法
  20. 网站建设入门技术导航

热门文章

  1. 对合成大西瓜修改图片的实践
  2. 高效开发工具使用技巧
  3. 求一个n*n矩阵对角线元素之和C语言,求一个n*n矩阵主对角线之和,次对角线元素之和.用指针完成...
  4. 监听通知栏内容,获取通知栏消息,安卓原生SDK扩展
  5. hbuild无法与这台计算机上的,HBuilderX无法连接网络
  6. 关于阶乘的计算出现负数,数据溢出的问题
  7. 用LangChain构建大语言模型应用
  8. 如何对文本框进行功能测试
  9. 小红书最新用户量数据_近半年DAU峰回路转 重新审视小红书用户价值
  10. 史上最强最逼真的游戏