server.c
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
if(argc != 2)
{
printf("input ip\n");
exit(0);
}
// 创建套接字,买手机
int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if(sock_fd == -1)
{
perror("sock failed:");
exit(0);
}
// 设置手机卡
struct sockaddr_in sAddr;
memset(&sAddr,0,sizeof(sAddr));//清空
// 设置本机的ip与端口号
sAddr.sin_family = AF_INET;// ipv4
sAddr.sin_port = htons(atoi(argv[1])); // 转为网络端口 htons:本机转网络
sAddr.sin_addr.s_addr = htonl(INADDR_ANY);// 自动获取本机ip,所有客户都能连接
// sAddr.sin_addr.s_addr = inet_addr("123.57.146.192");//阿里云
socklen_t len = sizeof(sAddr);
// 绑定ip
int ret = bind(sock_fd, (struct sockaddr *)&sAddr, len);
if(ret == -1)
{
perror("bind faield:");
exit(0);
}
// 监听
listen(sock_fd, 100);
printf("Server listening\n");
// 等待连接,没有人连接会阻塞直到客户端连接
// 接收对端的ip与端口号
struct sockaddr_in cAddr;
memset(&cAddr,0,sizeof(cAddr));
// 连接成功会返回以连接套接字,用于与客户端通信
int accept_fd = accept(sock_fd, (struct sockaddr *)&cAddr, &len);
if(accept_fd == -1)
{
perror("accept failed:");
return -1;
}
printf("连接成功\n");
//获取端口号
char client_port[100] ={0};
//ntons将网络端口转为本地端口
sprintf(client_port,"%d",htons(cAddr.sin_port));
//将此端口回发
ret = write(accept_fd,client_port,strlen(client_port));
if(ret < 0)
{
perror("回发失败:");
return -1;
}
// 关闭连接
close(sock_fd);
close(accept_fd);
return 0;
}
client.c
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
if(argc != 3)
{
printf("input ip && port : \n");
return -1;
}
// 创建套接字
int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if(sock_fd == -1)
{
perror("sock failed:");
exit(0);
}
// 设置服务器ip
struct sockaddr_in sAddr;
memset(&sAddr,0,sizeof(sAddr));
sAddr.sin_family = AF_INET;// ipv4
sAddr.sin_port = htons(atoi(argv[2])); // 转为网络端口
sAddr.sin_addr.s_addr = inet_addr(argv[1]);// argv[1]是服务器ip
socklen_t len = sizeof(sAddr);
//连接
int ret = connect(sock_fd, (struct sockaddr *)&sAddr, len);
if(ret == -1)
{
perror("connect failed:");
exit(0);
}
printf("Connected to server\n");
//获取服务器回发的端口号
char recv_port[100] = {0};
read(sock_fd,recv_port,100);
printf("recv_port : %s\n",recv_port);
//获取本机端口号
struct sockaddr_in cAddr;
memset(&cAddr, 0, sizeof(cAddr));
getsockname(sock_fd,(struct sockaddr *)&cAddr,&len);
printf("my port : %d\n",ntohs(cAddr.sin_port));
// 关闭连接
close(sock_fd);
return 0;
}