C++学习笔记:Socket tcp

tcp服务器端:

  1.常用函数sfd = socket(AF_INET,SOCK_STREAM,0);

  用来创建一个socket  sfd,但此时并未绑定到主机,此时需要一个结构体sockadd_in 来配合socketsfd来进行绑定主机

  同时需要对此结构体进行初始化,将其协议族改为AF_INET,使用inet_addr,htons对其地址端口号进行转换成二进制

    struct sockaddr_in ser;
    memset(&ser,0,sizeof(ser));
    ser.sin_family=AF_INET;
    ser.sin_port=htons(atoi(argv[2]));//一定要用htons
    ser.sin_addr.s_addr=inet_addr(argv[1]);

  2.讲socket的文件描述符与地址进行绑定bind

  bind(sfd,(struct sockaddr*)&ser,sizeof(struct sockaddr));

  原型:int bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen);

  当返回值为-1是出错。

#include "func.h"
//使用socket接口实现tcp通信的服务器端
int main(int argc,char** argv)
{
    if(argc!=3)
    {
        printf("error args\n");
        return -1;
    }
    int sfd=socket(AF_INET,SOCK_STREAM,0);
    if(-1==sfd)
    {
        perror("socket");
        return -1;
    }    
    printf("sfd=%d\n",sfd);
    struct sockaddr_in ser;
    memset(&ser,0,sizeof(ser));
    ser.sin_family=AF_INET;
    ser.sin_port=htons(atoi(argv[2]));//一定要用htons
    ser.sin_addr.s_addr=inet_addr(argv[1]);
    int ret;
    //给sfd绑定IP地址和端口号
    ret=bind(sfd,(struct sockaddr*)&ser,sizeof(struct sockaddr));
    if(-1==ret)
    {
        perror("bind");
        return -1;
    }
    ret=listen(sfd,10);
    if(-1==ret)
    {
        perror("listen");
        return -1;
    }
    printf("listen success\n");
    struct sockaddr_in client;
    memset(&client,0,sizeof(client));
    int addrlen=sizeof(struct sockaddr);
    int new_fd=accept(sfd,(struct sockaddr*)&client,&addrlen);
    if(-1==new_fd)
    {
        perror("accept");
        return -1;
    }
    printf("new_fd=%d\n",new_fd);
    printf("client IP=%s,client port=%d\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));
    char buf[128]={0};
    ret=recv(new_fd,buf,sizeof(buf),0);
    if(-1==ret)
    {
        perror("recv");
        return -1;
    }
    printf("%s\n",buf);
    ret=send(new_fd,"I am server",11,0);
    if(-1==ret)
    {
        perror("send");
        return -1;
    }
    return 0;
}
    
    
View Code

  3.对端口进行监听,并设置监听上限

  listen(sfd,10);--->int listen(int sockfd,int backlog);

  当失败时会返回-1,backlog是监听上线数(sock_stream,sock_seqpacket)

  4.使用accept(sfd,,(struct sockaddr*)&client,&addrlen);在此等待接收

  注意的是这里是struct sockaddr而不是sockadd_in,但是你绑定的是后者

         accept函数非常地痴情,痴心不改:如果没有客户端套接字去请求,它便会在那里一直痴痴地等下去,直到永远(注意, 此处讨论的是阻塞式的  socket.  如果是非阻塞式的socket, 那么accept函数就没那么痴情了, 而是会立即返回, 并意犹未尽地对未来的客户端扔下一句话: 我等了你, 你不来, 那就算了, 我懒得鸟你)。

    int new_fd=accept(sfd,(struct sockaddr*)&client,&addrlen);

 

客户端:
  同上一道三部。但是注意端口号写的可是服务器的哦、、

  不同的是connect函数代替accept函数

    ret=connect(sfd,(struct sockaddr*)&ser,sizeof(struct sockaddr));

posted @ 2016-07-11 20:39  Jarvis.cpp  阅读(256)  评论(0编辑  收藏  举报