端口号:其实实质就是一个数字编号,用来在一台电脑主机中,主机的操作系统中,唯一标识一个能上网的进程,当前OS中是唯一的,跟IP地址会一起投入到每一个数据包中
IP地址精确到某一台电脑
端口号精确到这台电脑的哪一个进程
所以IP地址和端口号是打包在一起不分家的,这两个是同时具备才能工作的,
bind 是把当前的电脑的IP 端口号跟socket绑定起来
listen就是用来监听的
服务器的代码
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define SVRPORT 6003
#define SRVADDR "192.168.0.102" //ifconfig 看到的
#define BACKLOG 10
int main(void)
{
//先socket打开一个文件描述符
int sockfd = -1,ret = -1;
struct sockaddr_in srvaddr = {0};
struct sockaddr_in clnaddr = {0};
socklen_t len = 0;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0)
{
perror("socket");
return -1;
}
printf("sockfd = %d.\n", sockfd);
//然后,bind绑定sockfd和(IP + 端口号)
srvaddr.sin_family = AF_INET; //设置地址族为IPV4
srvaddr.sin_port = htons(SVRPORT);//设置地址的端口号
srvaddr.sin_addr.s_addr = inet_addr(SRVADDR);//设置IP地址
ret = bind(sockfd, (const struct sockaddr *)&srvaddr, sizeof(srvaddr));
if(ret < 0)
{
perror("bind");
return -1;
}
//第三步 listen 监听端口 监听当前的端口号的端口
ret = listen(sockfd, BACKLOG);//阻塞等待监听服务器
if(ret < 0)
{
perror("listen");
return -1;
}
//第四步 阻塞等待客户端接入
ret = accept(sockfd, (struct sockaddr *)&clnaddr, &len);
printf("hahaha ret = %d.\n", ret);
return 0;
}
客户端的代码
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define SRVADDR "192.168.0.102" //服务器开放给我们的IP地址和端口号
#define SVRPORT 6003
int main(void)
{
//先socket打开一个文件描述符
int sockfd = -1,ret = -1;
struct sockaddr_in srvaddr = {0};
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0)
{
perror("socket");
return -1;
}
printf("sockfd = %d.\n", sockfd);
//然后,connect连接服务器
srvaddr.sin_family = AF_INET; //设置地址族为IPV4
srvaddr.sin_port = htons(SVRPORT);//设置地址的端口号
srvaddr.sin_addr.s_addr = inet_addr(SRVADDR);//设置IP地址
ret = connect(sockfd, (const struct sockaddr *)&srvaddr, sizeof(srvaddr));
if(ret < 0)
{
perror("connect");
return -1;
}
printf("connect rst ret = %d.\n", ret);
return 0;
}
accept是阻塞的,返回值是fd,为连接新建的fd,accept能正确返回说明fd服务器与客户端建立连接了,读写操作就由accept返回了,以后的read write send recieve 都是基于这个
socket返回的fd是监听文件描述符,是描述监听客户端的过程,不能用来读写
accept返回的fd叫做连接fd,是链接之后服务器和客户端读写的描述符
客户端发送服务器接收 服务器代码
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define SVRPORT 7003
#define SRVADDR "192.168.43.162" //ifconfig 看到的
#define BACKLOG 10
char buf[100] = {0};
int main(void)
{
//先socket打开一个文件描述符
int sockfd = -1,ret = -1;
struct sockaddr_in srvaddr = {0};
struct sockaddr_in clnaddr = {0};
socklen_t len = 0;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0)
{
perror("socket");
return -1;
}
printf("sockfd = %d.\n", sockfd);
//然后,bind绑定sockfd和(IP + 端口号)
srvaddr.sin_family = AF_INET; //设置地址族为IPV4
srvaddr.sin_port = htons(SVRPORT);//设置地址的端口号
srvaddr.sin_addr.s_addr = inet_addr(SRVADDR);//设置IP地址
//bind(sockfd, (const struct sockaddr *)&srvaddr, sizeof(srvaddr));
ret = bind(sockfd, (const struct sockaddr *)&srvaddr, sizeof(srvaddr));
if(ret < 0)
{
perror("bind");
return -1;
}
//第三步 listen 监听端口 监听当前的端口号的端口
ret = listen(sockfd, BACKLOG);//阻塞等待监听服务器
if(ret < 0)
{
perror("listen");
return -1;
}
//第四步 阻塞等待客户端接入
ret = accept(sockfd, (struct sockaddr *)&clnaddr, &len);
printf("hahaha ret = %d.\n", ret);
recv(ret, buf, sizeof(buf), 0);
printf("rec %s\n", buf);
return 0;
}
客户端代码
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#define SRVADDR "192.168.43.162" //服务器开放给我们的IP地址和端口号
#define SVRPORT 7003
char buf[100] = {0};
int main(void)
{
//先socket打开一个文件描述符
int sockfd = -1,ret = -1;
struct sockaddr_in srvaddr = {0};
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0)
{
perror("socket");
return -1;
}
printf("sockfd = %d.\n", sockfd);
//然后,connect连接服务器
srvaddr.sin_family = AF_INET; //设置地址族为IPV4
srvaddr.sin_port = htons(SVRPORT);//设置地址的端口号
srvaddr.sin_addr.s_addr = inet_addr(SRVADDR);//设置IP地址
ret = connect(sockfd, (const struct sockaddr *)&srvaddr, sizeof(srvaddr));
if(ret < 0)
{
perror("connect");
return -1;
}
printf("connect rst ret = %d.\n", ret);
strcpy(buf, "Hello world!");
ret = send(sockfd, buf, strlen(buf), 0);
printf("num is %d\n", ret);
return 0;
}