tcp服务器和客户端代码实现

服务器

编程流程:

  1. int socket() 创建一个socket
    返回值:出错返回-1 成功返回socket文件描述符
  2. int bind() 命名绑定,确定IP+port 只有在命名之后客户端才知道如何连接它
    返回值:失败返回-1 成功返回0
    进行绑定步骤时要进行主机字节序和网络字节序的转换和IP地址点分十进制的字符串类型和整型值之间的转换
  3. int listen() 启动监听 ,socket命名绑定了之后还不能马上接受客户的链接,需要先启动监听来创建一个监听队列用于存放待处理的客户链接,连接队列的大小最好设置为5
  4. int accept() 与客户端建立连接
    返回值:每进行一次连接若失败则返回-1,若成功则会返回一个新的文件描述符,该文件描述符唯一的标识了被连接的服务端。
  5. recv()/send() 发送接收消息,若客户端不发送消息整个进程会阻塞在recv,只要客户端有输入 返回值一定为1
  6. connect() 客户端向服务器发送请求链接的申请
  7. close() 关闭文件描述符断开连接

服务器:
socket() bind() listen() while{ accept() recv()/send() close() }
客户端:
socket() connect() send()/recv() close()
tcp服务器

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
/*服务器端*///思考?:怎样做到多个客户端同时发送消息
int main()
{
    int sockfd = socket(AF_INET,SOCK_STREAM,0);//创建监听套接字
    if( sockfd == -1)
    {
        return 0;
    }
    struct sockaddr_in saddr,caddr;//服务器ip,port, 客户端的ip,port(套接字地址)
    memset(&saddr,0,sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(6000);//1024知名端口,4096保留端口,大于4096临时端口
    saddr.sin_addr.s_addr = inet_addr("127.0.0.1");//测试地址。inet_addr()将字符串转化成无符号整形-》//初始化完成
    int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));//绑定,命名套接字
    if(res == -1)
    {
        printf("连接服务器失败\n");
        return 0;
    }
    res = listen(sockfd,5);//linux 5 指的是监听已完成三次握手的监听队列的大小
    assert( res != -1);
    while(1)
    {
        int len = sizeof(caddr);
        int c = accept(sockfd,(struct sockaddr*)&caddr,&len);//接受连接,可能阻塞
        if(c<0)
        {
            continue;
        }
        printf("accept c=%d\n",c);//c连接套接字

        while(1)
        {
            char buff[128]={0};
            int n=recv(c,buff,127,0);//recv 接收    recv返回值==0说明对端关闭  <0说明错误
            if( n == 0)
            {
                break;
            }
            printf("buff(%d)=%s\n",n,buff);
            send(c,"ok",2,0);//send 发送
        } 
        close(c);
        printf("client close\n");
       
    }


}

客户端

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
/*客户端*/
int main()
{
    int sockfd = socket(AF_INET,SOCK_STREAM,0);//创建套接字
    if( sockfd == -1)
    {
        printf("create socket err\n");
        return 0;
    }
    //bind()可以绑定,但是一般不绑定
    struct sockaddr_in saddr;
    memset(&saddr,0,sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(6000);
    saddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    int res = connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
    if( res == -1 )
    {
        printf("bind err\n");
        return 0;
    }
    while(1)
    {
        char buff[128]={0};
        printf("input:\n");
       fgets(buff,128,stdin);
       
       if(strncmp(buff,"end",3)==0)
       {
           break;
       }   
       send(sockfd,buff,strlen(buff),0);

       memset(buff,0,128);
       recv(sockfd,buff,127,0);
       printf("buff=%s\n",buff);
    }
    close(sockfd);
}
上一篇:B2. Character Swap (Hard Version)


下一篇:Linux/Unix 系统编程 — FTP客户端