Linux下的socket演示程序
本节演示了Linux下的代码,server.cpp是服务器端代码,client.cpp是客户端代码,要实现的功能是:客户端从服务器读取一个字符串并打印出来。
服务器端代码 server.cpp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #include <netinet/in.h>
int main(){ int serv_sock = socket(AF_INET,SOCK_STREAM,IPPROTP_TCP); struct sockaddr_in serv_addr; memset(&serv_addr,0,sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); serv_addr.sin_port = htons(1234); bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr)); listen(serv_sock,20); struct sockaddr_in clnt_addr; socklen_t clnt_addr_size = sizeof(clnt_addr); int clnt_sock = accept(serv_sock,(struct sockaddr*)&clnt_addr,&clnt_addr_size); char str[] = "http://1905060202.github.io"; write(clnt_sock,str,sizeof(str)); close(slnt_sock); close(serv_sock); return 0; }
|
客户端代码 client.cpp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h>
int main(){ int sock = socket(AF_INET,SOCK_STREAM,0); struct sockaddr_in servaddr; memset(&serv_addr,0,sizeof(serv_addr)); serv_addr.sin.family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1") serv_addr.sin_port = htons(1234); connect(sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr)); char buffer[40]; read(sock,buffer,sizeof(buffer)-1); printf("Message form server :%s\n",buffer); close(sock); return 0; }
|
启动一个终端(shell),先编译server.cpp并运行:
1 2 3
| [admin@loaclhost ~]$g++server.cpp -o server [admin@localhost ~]$./client Message form server.http:
|
client接收到从server发送过来的字符串就运行结束了,同时server完成发送字符串的任务也运行结束了。大家可以通过两个打开的终端来观察。
client运行后,通过connect()函数向server发起请求,处于监听状态的server被激活,执行accept()函数,接收客户端的请求,然后执行write()函数向client传回数据。client接收到传回的数据后,connect()函数就运行结束了,然后使用read()将数据读取出来。
源码解析
server.cpp:
第11行通过socket()函数创建了一个套接字,参数AF_INET表示使用IPv4地址,SOCK_STREAM表示使用面向连接的套接字,IPPROTP_TCP表示使用TCP协议。在Linux中,socket也是一种文件,有文件描述符,可以使用write()或read()函数进行I/O操作。
第19行通过bind()函数将套接字serv_sock与特定的IP地址和端口绑定,IP地址和端口都保存在sockaddr_in结构体中。
socket()函数确定了套接字的各种属性,bind()函数让套接字与特定的IP地址和端口对应起来,这样客户端才能连接到该套接字。
第22行让套接字处于被动监听的状态。所谓被动监听,是指套接字一直处于“睡眠”状态,直到客户端发起请求才会被“唤醒”
第27行的accept()函数用来接收客户端的请求。程序一旦执行到accept()就会被阻塞,直到客户端发起请求。
第31行的write()函数用来向套接字文件中写入数据,也就是向客户端发送数据。
client.cpp: