(五)socket实践编程

1、服务器端程序编写

(1)socket
(2)bind
(3)listen
(4)accept,返回值是一个fd,accept正确返回就表示我们已经和前来连接我的客户端之间建立了一个TCP连接了,以后我们就要通过这个连接来和客户端进行读写操作,读写操作就需要一个fd,这个fd就由accept来返回了。
注意:socket返回的fd叫做监听fd,是用来监听客户端的,不能用来和任何客户端进行读写;accept返回的fd叫做连接fd,用来和连接那端的客户端程序进行读写。
2、客户端程序编写
(1)socket
(2)connect

概念:端口号,实质就是一个数字编号,用来在我们一台主机中(主机的操作系统中)唯一的标识一个能上网的进程。端口号和IP地址一起会被打包到当前进程发出或者接收到的每一个数据包中。每一个数据包将来在网络上传递的时候,内部都包含了发送方和接收方的信息(就是IP地址和端口号),所以IP地址和端口号这两个往往是打包在一起不分家的。

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>



#define SERPORT        9003
#define SERADDR        "192.168.1.141"        // ifconfig看到的
#define BACKLOG        100


char recvbuf[100];


int main(void)
{
    // 第1步:先socket打开文件描述符
    int sockfd = -1, ret = -1, clifd = -1;
    socklen_t len = 0;
   // sockaddr_in:为IPV4数据结构类型,sockaddr_in6位IPV6数据结构类型。sockaddr兼容这两种
struct sockaddr_in seraddr = {0}; struct sockaddr_in cliaddr = {0}; char ipbuf[30] = {0}; sockfd = socket(AF_INET, SOCK_STREAM, 0); if (-1 == sockfd) { perror("socket"); return -1; } printf("socketfd = %d. ", sockfd); // 第2步:bind绑定sockefd和当前电脑的ip地址&端口号 seraddr.sin_family = AF_INET; // 设置地址族为IPv4
   // 设置地址的端口号信息,以太网通信,我们默认为大端模式,这里端口号,我们要进行转换,htons表示将整型变量从主机字节顺序转变成网络字节顺序, 就是整数在地址空间存储方式变为:高字节存放在内存的低地址处
   seraddr.sin_port = htons(SERPORT);   
                                                  //
   //设置IP地址,inet_addr将10进制字符串IP地址转换为二进制网络字节序,这个函数里面做了大端处理,不过inet_addr只适用于IPV4,现在一般使用inet_pton,它适用于IPV4和IPV6 seraddr.sin_addr.s_addr = inet_addr(SERADDR);                              ret = bind(sockfd, (const struct sockaddr *)&seraddr, sizeof(seraddr)); if (ret < 0) { perror("bind"); return -1; } printf("bind success. "); // 第三步:listen监听端口,BACKLOG为可挂载的监听到的个数 ret = listen(sockfd, BACKLOG); // 阻塞等待客户端来连接服务器 if (ret < 0) { perror("listen"); return -1; } // 第四步:accept阻塞等待客户端接入 clifd = accept(sockfd, (struct sockaddr *)&cliaddr, &len); printf("连接已经建立,client fd = %d. ", clifd); /* // 建立连接之后就可以通信了 // 客户端给服务器发 ret = recv(clifd, recvbuf, sizeof(recvbuf), 0); printf("成功接收了%d个字节 ", ret); printf("client发送过来的内容是:%s ", recvbuf); */ /* // 客户端反复给服务器发 while (1) { ret = recv(clifd, recvbuf, sizeof(recvbuf), 0); //printf("成功接收了%d个字节 ", ret); printf("client发送过来的内容是:%s ", recvbuf); memset(recvbuf, 0, sizeof(recvbuf)); } */ // 服务器给客户端发 strcpy(recvbuf, "hello world."); ret = send(clifd, recvbuf, strlen(recvbuf), 0); printf("发送了%d个字符 ", ret); return 0; }

  

原文地址:https://www.cnblogs.com/zhangshenghui/p/6042826.html