TCP/IP网络编程
第一章 理解网络编程和套接字
实现
- 先准备一个linux的操作系统然后用xshell连上
CentOS7安装以及Xshell连接常见问题解决_jump_into_zehe的博客-CSDN博客
- 下载gcc
[root@localhost tcp]# which gcc
/usr/bin/which: no gcc in (/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/hongzehe/.local/bin:/home/hongzehe/bin)
[root@localhost tcp]# yum -y install gcc automake autoconf libtool make
- 创建服务器端C文件
mkdir tcpip
cd tcpip
创建hello_server.c并将下面的代码拷贝进去
vi hello_server.c
代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h>
void error_handling(char *message)
int main(int argc, char *argv[])
{
int serv_sock; //服务器socket,其实就是一个文件描述符fd
int clnt_sock; //客户端socket
struct sockaddr_in serv_addr; //服务器ip port
struct sockaddr_in clnt_addr; //客户端ip port
socklen_t clnt_addr_size;
char message[]="Hello World!!!"; //要传输的数据
if(argc!=2){
printf("Usage : %s <port>\n", argv[0]);
exit(1);
}
serv_sock=socket(PF_INET, SOCK_STREAM, 0); //获得服务器socket
if(serv_sock == -1)
error_handling("socket() error");
memset(&serv_addr,0,sizeof(serv_addr)); //初始化为0
serv_addr.sin_family=AF_INET; //ip版本
serv_addr.sin_addr.s_addr=htonl(INADDR_ANY); //ip地址
serv_addr.sin_port=htons(atoi(argv[1])); //端口
if(bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr))==-1) //对socket绑定ip地址和端口号
error_handling("bind() error");
if(listen(serv_sock, 5)==-1) //使服务器监听外来连接
error_handling("listen() error");
clnt_addr_size=sizeof(clnt_addr);
clnt_sock=accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size); //获取外来连接的客户端socket
if(clnt_sock==-1)
error_handling("accept() error");
write(clnt_sock, message, sizeof(message)); //写数据
close(clnt_sock); //关闭文件
close(serv_sock);
return 0;
}
void error_handling(char *message)
{
fputs(message,stderr);
fputc('\n',stderr);
exit(1);
}
编译该文件
gcc hello_server.c -o hello_server
编译完之后会生成hello_server可执行文件,执行该程序
./hello_server 9190 #在端口9190处监听
- 创建客户端程序
vi hello_client.c
代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h>
void error_handling(char *message);
int main(int argc, char * argv[])
{
int sock;
struct sockaddr_in serv_addr;
char message[30];
int str_len;
if(argc!=3){
printf("Usage: %s <IP> <port>\n", argv[0]);
exit(1);
}
sock=socket(PF_INET, SOCK_STREAM, 0); //获取客户端socket
if(sock == -1)
error_handling("socket() error");
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr=inet_addr(argv[1]); //设置服务器ip地址
serv_addr.sin_port=htons(atoi(argv[2])); //设置服务器监听的端口号
if(connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1) //连接服务器
error_handling("connect() error");
str_len=read(sock,message,sizeof(message)-1); //读数据
if(str_len==-1)
error_handling("read() error");
printf("Message from server : %s \n",message);
close(sock);
return 0;
}
void error_handling(char *message)
{
fputs(message,stderr);
fputc('\n',stderr);
exit(1);
}
编译文件
gcc hello_client.c -o hello_client
在xshell复制一个会话开启一个新的终端然后执行该文件,第一个终端在等待连接,没有收到连接程序会一直运行
./hello_client 127.0.0.1 9190
这时候我们就会收到来自服务器端的响应啦!
[root@localhost tcp]# ./hello_client 127.0.0.1 9190
Message from server : Hello World!!!
原理
在linux中,socket和文件是没有区别的,linux中,一切皆文件,服务器和客户端之间的数据传输在linux中其实就是一个写文件的过程,而socket是用来连接网络的工具,所以我们使用socket编程时是不需要去关心我们的数据到底是如何从一台电脑传输到另一台的,socket已经帮我们实现了,我们要做的就是编写服务器和客户端的程序
参考
《TCP/IP网络编程》 【韩】 尹圣雨 著 金国哲 译