大家好,又见面了,我是你们的朋友全栈君。
一、socket介绍
socket起源于linux,在Linux中,一个非常重要的思想就是“一切皆文件”,一切行为皆可描述为“打开文件—->读写文件—–>关闭文件”,socket可以理解成一种特殊的文件,把对底层tcp/ip网络的调用封装起来,提供给用户一些调用的接口来是实现网络编程。
引用一张图清晰的解释,此图来自CMU ICS
我们都知道网络通信需要知道一个三元组——ip、protocol、port,来唯一的标识网络中的某个主机上的某个进程,从而实现不同主机间进程的通信。
具体实现:服务器端:创建socket,返回一个socket描述符,和服务器地址和端口bind,listen函数开启监听想要连接的客户端,accept接受客户端的连接请求,为客户端分配一个专属的socket连接,在传输完成后close关闭连接
相比之下,客户端就比较简单了,socket创建,connect,read and write,然后close,下面实现了一个简单的多线程网络聊天。
二、简单聊天程序
serve.c
代码语言:javascript复制#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> #define PORT 6666 //端口号 #define SIZE 1024 //定义的数组大小 int create_socket() //创建套接字和初始化以及监听函数 { int listen_socket = socket(AF_INET, SOCK_STREAM, 0); //创建一个负责监听的套接字 协议族,协议类型,具体协议,返回大于0表示创>建成功 if(listen_socket< 0) { perror("socket"); return -1; } struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); //服务器端地址结构 addr.sin_family = AF_INET; /* Internet地址族 */ addr.sin_port = htons(PORT); /* 端口号 */ addr.sin_addr.s_addr = htonl(INADDR_ANY); /* 服务器IP地址 */ if(bind(listen_socket, (struct sockaddr *)&addr, sizeof(addr))==-1){ perror("bind"); return -1; } if(listen(listen_socket, 4) == -1) //监听 { perror("listen"); return -1; } return listen_socket; } //信息处理函数,功能是将客户端传过来的小写字母转化为大写字母 void *handle_client(void *ptr){ int fd=*(int *)ptr; printf("the new connect_socket is %dn",fd); char buf[SIZE]; while(1) { int ret = read(fd, buf, SIZE-1); if(ret == -1) { perror("read"); break; } if(ret == 0) break; buf[ret] = '