调用socket函数返回一个文件描述符sockfd
专用socket地址
UNIX 本地协议簇
struct sockaddr_un
TCP/IP协议簇
struct sockaddr_in //IPV4
struct sockaddr_in6 //IPV6
struct sockaddr_in {
short sin_family; //address family 协议簇
u_short sin_port; //16 bit TCP/UDP port number 端口号
struct in_addr sin_addr; //32 bit IP address 网络字节序(IP地址转化后)
char sin_zero[8]; //not use, for align
};
给sockfd文件描述符 命名
int bind(int sockfd, const struct sockaddr* my_addr ,socklen_t addrlen);
将my_addr指向的socket地址
监听socket
int listen(int sockfd,int backlog); //backlog指最大监听队列长度
int accept(int sockfd ,struct sockaddr *addr ,socklen_t *addrlen);
accept阻塞等待客户连接,返回新的套接字,该套接字可以和客户端通信write或read
socket()创建sockfd文件描述符
这里 专用socket地址 可以指定协议簇、目标服务器的端口号 和 目标服务器的网络字节序
connect() //客户端操作
int connect(int sockfd ,const struct sockaddr *serv_addr ,socklen_t addrlen);
connect()函数将创建的文件描述符 和 专用的socket地址 连接 ,
环境 linux
server.c
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/types.h>
#include <arpa/inet.h> //struct sockaddr_in
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#define SERV_PORT 9000
int main(int argc , char *const * argv){
int listenfd = socket(AF_INET,SOCK_STREAM,0); //参数(2,2,0) listenfd是文件
struct sockaddr_in serv_addr;
memset(&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port= htons(SERV_PORT); //端口号
serv_addr.sin_addr.s_addr =htonl(INADDR_ANY);
bind(listenfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)); //套接字和结构体sockaddr_in 进行绑定
listen(listenfd,32); //请求数不超过32
int connfd;
const char * pcontent = "I sent sth to client";
for(;;){
connfd =accept(listenfd,(struct sockaddr *)NULL ,NULL); //阻塞等待客户端连接 accept返回的是客户端套接字,往这个套接字写东西可以和客户端通信
write(connfd ,pcontent ,strlen(pcontent));
close(connfd);//关闭后等待下一个客户端连接
}
close(listenfd);
return 0;
}
客户端
client.c
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h> //socket 函数
#include <arpa/inet.h> //sockaddr_in
#define SERV_PORT 9000
int main(int argc ,char *const *argv){
int sockfd = socket(AF_INET ,SOCK_STREAM,0);
struct sockaddr_in serv_addr;
memset(&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family = AF_INET; //选择协议簇 IPV4
serv_addr.sin_port = htons(SERV_PORT); //端口
if(inet_pton(AF_INET,"192.168.1.126",&serv_addr.sin_addr) <=0){
printf("调用inet_pton()失败,退出\n");
exit(1);
}
if(connect(sockfd ,(struct sockaddr *)&serv_addr ,sizeof(serv_addr)) <0){
printf("调用connect()函数失败,退出\n");
exit(1);
}
int n;
char recvline[1000+1];
while( ( n = read(sockfd ,recvline ,1000) ) >0){ // 不是 == 判断 ,而是赋值 =
recvline[n] =0;
printf("收到的内容:%s\n",recvline);
}
close(sockfd);
printf("程序执行完毕,退出 \n");
return 0;
}
效果
开启两个bash
原文:https://www.cnblogs.com/appearAndLeave/p/14785282.html