//客户端代码
#include <arpa/inet.h>
#include <netinet/in.h>#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
//client端tcp/ip的模型
/* 1.socket---->connect---->write(发送你的数据给client)----->read(从server读数据)--->close
*/
int main()
{
//可以通过man查看sockaddr_in 这个结构到底包含什么变量
struct sockaddr_in address;//定义了一个sockaddr_in的结构,它是一个IP地址的结构
int len;//len代表这个结构的长度
int socket_fd;//文件描述符
//在进行socket编程时要初始化socket,返回的是一个文件描述符
//因为是tcp的socket,所以第2个参数为SOCK_STREAM, 如果是udp的socket,则是SOCK_DGRAM
//第三个参数默认为零
//socket的函数返回值是一个很小的文件描述符,下面的read和write函数都是通过这个文件描述符
//和另一个程序进行通信的
if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("create sockt is error\n");
return EXIT_FAILURE;
}
//养成一个好习惯,用一个变量之前,要进行初始化
memset(&address, 0, sizeof(address));
//指定一个端口号:8080,htons:将short类型从host字节类型到net字节类型转化
address.sin_port = htons(8080);
设置结构地址类型为TCP/IP地址
address.sin_family = AF_INET;
将字符串类型的IP地址转化为int,赋给addr结构成员.
address.sin_addr.s_addr = inet_addr("127.0.0.1");
//connect如果成功的话是返回0,失败返回1
//(struct sockaddr*)&address的原因是历史原因,所以要强制类型转换
int n = connect(socket_fd, (struct sockaddr*)&address, sizeof(address));
char buf[1024];
memset(buf, 0, sizeof(buf));
char *s = "Hello Silence";
strncpy(buf, s, strlen(s));
//从client发数据到server
write(socket_fd, s, strlen(buf));
memset(buf, 0, sizeof(buf));
//从server读数据
read(socket_fd, buf, sizeof(buf));
printf("buf: %s\n", buf);
//关闭文件描述符
close(socket_fd);
return EXIT_SUCCESS;
}
-------------------------------------------------------------------------------------------
服务端代码
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
/*
server端的tcp/ip模型
1.socket--->connect---->bind---->listen---->read(从client读数据)---->write(发送数据给cleint)-->close
在read这里就是可以对client发来的数据进行操作,
*/
int main()
{
//这里需要2个结构,一个是代表server的结构
//另外一个是代表client的结构
struct sockaddr_in client_address, server_address;
//client_len代表client_address的长度
int client_len, server_len;
//client_fd和server_fd是2个文件描述符,进行read和write操作
int client_fd, server_fd;
int n;
//养成一个好习惯
memset(&client_address, 0, sizeof(client_address));
memset(&server_address, 0, sizeof(server_address));
//初始化socket
server_fd = socket(AF_INET, SOCK_STREAM, 0);
设置结构地址类型为TCP/IP地址
server_address.sin_family = AF_INET;
//将本地字节顺序转化为网络字节顺序
server_address.sin_port = htons(8080);
//INADDR_ANY代表这个server上所有的地址
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
//连接函数
n = connect(server_fd, (struct sockaddr*)&server_address, sizeof(server_address));
if (n == 0)
{
printf("connect is error\n");
return EXIT_FAILURE;
}
//将IP与server程序绑定
bind(server_fd, (struct sockaddr*)&server_address, sizeof(server_address));
//server端开始listen,listen的第2个参数代表可以连接的client的最大数量
listen(server_fd, 10);
client_len = sizeof(client_address);
//accept会阻塞,直到有客户端连接过来,accept返回client的socket描述符
client_fd = accept(server_fd, (struct sockaddr*)&client_address, &client_len);
char buf[1024];
memset(buf, 0, sizeof(buf));
//通过文件描述符可以从client读取数据, 然后你可以做一系列操作之后,你可以发送数据给client
read(client_fd, buf, sizeof(buf));
printf("%s\n", buf);
strncpy(buf, "Welcome to net", strlen("Welcome to net"));
//通过文件描述符可以把数据发送给client
write(client_fd, buf, strlen(buf));
//关闭文件描述符
close(server_fd);
close(client_fd);
return EXIT_SUCCESS;
}