网络编程(一)----基础知识、数据流套接字

1、Linux支持6种类型的套接字接口,其中,最常用的是两种:数据流套接字和数据报套接字。

2、TCP/IP协议的套接字地址结构是sockaddr_in,在系统头文件<netinet/in.h>中定义。

     结构sockaddr_in中的TCP或UDP端口号sin_port和IP地址sin_addr都是以网络字节顺序存储的。

3、面向连接的套接字函数

(1)socket函数创建一个套接字描述符。

      #include <sys/types.h>

      #include <sys/socket.h> 

      int socket(int domain, int type, int protocol);

(2)connect函数用于与服务器建立一个连接。

     int connect(int sockfd, struct sockaddr * servaddr, int addrlen);

(3)bind函数将本地地址与套接字绑定在一起。

    int bind(int sockfd, struct sockaddr * myaddr, int addrlen);

(4)listen函数将一个套接字装换为倾听套接字(listening socket)

   int listen(int sockfd, int backlog);

(5)accept函数从倾听套接字的完成连接队列中接收一个连接。如果完成连接队列为空,那么这个进程休眠。

  int accept(int sockfd, struct sockaddr * addr, int *addrlen);

(6)close函数关闭一个套接字描述符。

  int close(int sockfd);

(7)函数read和write从套接字读和写数据。

  int read(int sockfd, char * buff, int len);

  int write(int sockfd, char * buff, int len);

4、面向连接套接字应用程序流程图

5、例子

编写一个客户机-服务器程序,其中客户机使用流套接字向服务器请求日期和时间,服务器在收到请求后,回答请求并显示出客户的地址。

(1) StreamSocketClient.c:

/*
 * StreamSocketClient.c
 *
 *  Created on: Aug 24, 2013
 *      Author: root
 */
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define MAXBUFFSIZE 256
#define PORT 6666
#define HOST_ADDR "127.0.0.1"

int main(){
    int sockfd, n;
    char recvbuff[MAXBUFFSIZE];
    struct sockaddr_in servaddr;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0){
        printf("Socket created failed.
");
        return -1;
    }
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(6666);
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    printf("connecting...
");
    if(connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
        printf("Connect server failed.
");
        return -1;
    }
    while((n = read(sockfd, recvbuff, MAXBUFFSIZE)) > 0){
        recvbuff[n] = 0;
        fputs(recvbuff, stdout);
    }
    if(n < 0){
        printf("Read failed.
");
        return -2;
    }
    return 0;
}

(2) StreamSocketServer.c:

/*
 * StreamSocketServer.c
 *
 *  Created on: Aug 24, 2013
 *      Author: root
 */
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define LISTENQ 5
#define MAXLINE 512

int main(){
    int listenfd, connfd;
    socklen_t len;
    struct sockaddr_in servaddr, cliaddr;
    char buff[MAXLINE];
    time_t ticks;
    listenfd=socket(AF_INET,SOCK_STREAM, 0);
    if(listenfd < 0){
        printf("Socket created failed.
");
        return -1;
    }
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(6666);
    if(bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0){
        printf("bind failed.
");
        return -1;
    }
    printf("listening ...
");
    listen(listenfd, LISTENQ);
    while(1){
        len = sizeof(cliaddr);
        connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &len);
        printf("connect from %s, port %d
", inet_ntoa(cliaddr.sin_addr.s_addr), ntohs(cliaddr.sin_port));
        ticks = time(NULL);                          //获取当前时间
        sprintf(buff, "% .24s
", ctime(&ticks));  //ctime函数:转换时间为标准时间字符串,并返回。
        write(connfd, buff, strlen(buff));
        close(connfd);
    }
}

具体流套接字通信结果:

原文地址:https://www.cnblogs.com/wangle1001986/p/3281903.html