connect()
作用:主动连接服务器
函数:
#include <sys/types.h>
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数:
sockfd:套接字文件描述符
addr:服务器地址结构体
addrlen:服务器地址长度
返回值:
成功:0
失败:-1,并设置error
地址结构:
struct sockaddr { //通用地址
sa_family_t sa_family;
char sa_data[14];
}
struct sockaddr_in { //IPv4地址结构
sa_family_t sin_family; /* address family: AF_INET */
in_port_t sin_port; /* port in network byte order */
struct in_addr sin_addr; /* internet address */
};
/* Internet address. */
struct in_addr { //网络字节序
uint32_t s_addr; /* address in network byte order */
};
例如:
//用IPv4结构体
struct sockaddr_in srvaddr;
memset(&srvaddr,0,sizeof(srvaddr));
srvaddr.sin_family = AF_INET;//指定地址族为IPv4的地址
srvaddr.sin_port = htons(6666);//端口号
srvaddr.sin_addr.s_addr = inet_addr("192.168.2.84");//将点分式的字符串转化32位的网络字节序
connect(sockfd,(struct sockaddr*)&srvaddr,sizeof(srvaddr));
printf(“-----------------------------我是分隔符--------------------------------------”)
实现服务器和客户端的简单对话
/*===============================================
* 文件名称:server_new.c
* 创 建 者:memories
* 创建日期:2023年05月19日
* 描 述:
================================================*/
实现服务器和客户端的简单对话,就是客户端发一条服务器接收到,服务器发一条客户端接收到,只能一条一条的来回发,有点鸡肋QAQ
#include <stdio.h>
#include "ip.h"
int main(int argc, char *argv[])
{
int sockfd,connfd;
if (argc <3)
{
fprintf(stderr,"usage: %s <SRVIP> <SRVPORT>\n",argv[0]);//提醒用户命令行该如何输入
return -1;
}
//1.创建套接字
if(0>(sockfd = socket(AF_INET,SOCK_STREAM,0)))
{
perror("socket");
return -1;
}
printf("socket---------------\n");
//2.绑定本机地址和接口
struct sockaddr_in srvaddr;
memset(&srvaddr,0,sizeof(srvaddr));
srvaddr.sin_family = AF_INET;
srvaddr.sin_port = htons(atoi(argv[2]));//PORT
srvaddr.sin_addr.s_addr = inet_addr(argv[1]);//IP
//srvaddr.sin_addr.s_addr = htonl(INADDR_ANY);//IP:0.0.0.0
if(0 > bind(sockfd,(struct sockaddr*)&srvaddr,sizeof(srvaddr)))
{
perror("bind");
return -1;
}
printf("bind---------------\n");
//3.设置监听套接字
if(0 > listen(sockfd,4))
{
perror("listen");
return -1;
}
printf("listen---------------\n");
//4.接受客户端的连接,并生成通信套接字
struct sockaddr_in cliaddr;
socklen_t addrlen = sizeof(cliaddr);
if(0 > (connfd = accept(sockfd,(struct sockaddr*)&cliaddr,&addrlen)))
{
perror("accept");
return -1;
}
printf("accept client:%s,%hu\n",inet_ntoa(cliaddr.sin_addr),ntohs(cliaddr.sin_port));
printf("accept success---------------\n");
//5.通信
int ret;
char buf[size];
while(1)
{
memset(buf,0,sizeof(buf));
ret = read(connfd,buf,sizeof(buf));
if(ret < 0)
{
perror("read");
break;
}
else if(ret == 0)
{
printf("client close\n");
break;
}
if(strncmp(buf,"quit",4)==0)
break;
printf("recv:");
fputs(buf,stdout);
printf("send:");
fgets(buf,sizeof(buf),stdin);
if(0 > write(connfd,buf,sizeof(buf)))
{
perror("write");
break;
}
}
//6.关闭套接字
close(sockfd);
close(connfd);
return 0;
}
/*===============================================
* 文件名称:client_new.c
* 创 建 者:memories
* 创建日期:2023年05月19日
* 描 述:
================================================*/
#include <stdio.h>
#include "ip.h"
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int sockfd;
if (argc <3)
{
fprintf(stderr,"usage: %s <SRVIP> <SRVPORT>\n",argv[0]);//提醒用户命令行该如何输入
return -1;
}
//1.创建套接字
if(0>(sockfd = socket(AF_INET,SOCK_STREAM,0)))
{
perror("socket");
return -1;
}
printf("socket---------------\n");
//2.主动连接服务器
struct sockaddr_in srvaddr;
memset(&srvaddr,0,sizeof(srvaddr));
srvaddr.sin_family = AF_INET;
srvaddr.sin_port = htons(atoi(argv[2]));//PORT
srvaddr.sin_addr.s_addr = inet_addr(argv[1]);//IP
if(0 > connect(sockfd,(struct sockaddr*)&srvaddr,sizeof(srvaddr)))
{
perror("connect");
return -1;
}
printf("connect---------------\n");
//5.循环读取文件内容,发送给服务器
int ret;
char buf[size];
int fd = open("file.text",O_RDONLY);
if(fd < 0)
{
perror("open");
return -1;
}
while(1)
{
char buf[size]={0};
int ret = read(fd,buf,sizeof(buf));
if(ret < 0)
{
perror("read");
break;
}
else if(ret == 0)
{
printf("finish\n");
break;
}
if( 0> (write(sockfd,buf,ret)))
{
perror("write");
break;
}
}
//6.关闭套接字
close(sockfd);
close(fd);
return 0;
}
printf(“-----------------------------我是分隔符--------------------------------------”)
实现服务器和客户端的全新对话
全新版本!
/*===============================================
* 文件名称:server_new1.c
* 创 建 者:memories
* 创建日期:2023年05月19日
* 描 述:
================================================*/
在./a.out后面命令端还有两个命令参数+++IP地址号+++端口号
实现服务器和客户端的全新对话,就是客户端发一条服务器接收到,服务器发一条客户端接收到,但能来回持续的发谁也不挡谁,再也不用害怕read和write的等待阻塞啦,因为采取了线程
在服务器里加入线程,实现发送的功能
在客户端里加入线程,实现接收的功能
#include <stdio.h>
#include "ip.h"
#include <pthread.h>
void *send_data(void *argv);
int main(int argc, char *argv[])
{
int sockfd,connfd;
if (argc <3)
{
fprintf(stderr,"usage: %s <SRVIP> <SRVPORT>\n",argv[0]);//提醒用户命令行该如何输入
return -1;
}
//1.创建套接字
if(0>(sockfd = socket(AF_INET,SOCK_STREAM,0)))
{
perror("socket");
return -1;
}
printf("socket---------------\n");
//2.绑定本机地址和接口
struct sockaddr_in srvaddr;
memset(&srvaddr,0,sizeof(srvaddr));
srvaddr.sin_family = AF_INET;
srvaddr.sin_port = htons(atoi(argv[2]));//PORT
srvaddr.sin_addr.s_addr = inet_addr(argv[1]);//IP
//srvaddr.sin_addr.s_addr = htonl(INADDR_ANY);//IP:0.0.0.0
if(0 > bind(sockfd,(struct sockaddr*)&srvaddr,sizeof(srvaddr)))
{
perror("bind");
return -1;
}
printf("bind---------------\n");
//3.设置监听套接字
if(0 > listen(sockfd,4))
{
perror("listen");
return -1;
}
printf("listen---------------\n");
//4.接受客户端的连接,并生成通信套接字
struct sockaddr_in cliaddr;
socklen_t addrlen = sizeof(cliaddr);
if(0 > (connfd = accept(sockfd,(struct sockaddr*)&cliaddr,&addrlen)))
{
perror("accept");
return -1;
}
printf("accept client:%s,%hu\n",inet_ntoa(cliaddr.sin_addr),ntohs(cliaddr.sin_port));
printf("accept success---------------\n");
//5.通信
int ret;
char buf[size];
pthread_t thread;
if(0!= pthread_create(&thread,NULL,send_data,(void *)&connfd))
{
printf("pthread create failed\n");
return -1;
}
while(1)
{
memset(buf,0,sizeof(buf));
ret = read(connfd,buf,sizeof(buf));
if(ret < 0)
{
perror("read");
break;
}
else if(ret == 0)
{
printf("client close\n");
break;
}
if(strncmp(buf,"quit",4)==0)
break;
printf("recv:");
fputs(buf,stdout);
}
//6.关闭套接字
close(sockfd);
close(connfd);
return 0;
}
void *send_data(void *argv)
{
int connfd = (*(int *)argv);
char buf[size]={0};
while(1)
{
printf("send:");
fgets(buf,sizeof(buf),stdin);
if(0 > write(connfd,buf,sizeof(buf)))
{
perror("write");
break;
}
if(strncmp(buf,"quit",4)==0)
exit(0);
}
}
hqyj@ubuntu:~/5.19$ cat client_new1.c
/*===============================================
* 文件名称:client_new1.c
* 创 建 者:memories
* 创建日期:2023年05月19日
* 描 述:
================================================*/
#include <stdio.h>
#include "ip.h"
#include <pthread.h>
void *send_data(void *argv);
int main(int argc, char *argv[])
{
int sockfd;
if (argc <3)
{
fprintf(stderr,"usage: %s <SRVIP> <SRVPORT>\n",argv[0]);//提醒用户命令行该如何输入
return -1;
}
//1.创建套接字
if(0>(sockfd = socket(AF_INET,SOCK_STREAM,0)))
{
perror("socket");
return -1;
}
printf("socket---------------\n");
//2.主动连接服务器
struct sockaddr_in srvaddr;
memset(&srvaddr,0,sizeof(srvaddr));
srvaddr.sin_family = AF_INET;
srvaddr.sin_port = htons(atoi(argv[2]));//PORT
srvaddr.sin_addr.s_addr = inet_addr(argv[1]);//IP
if(0 > connect(sockfd,(struct sockaddr*)&srvaddr,sizeof(srvaddr)))
{
perror("connect");
return -1;
}
printf("connect---------------\n");
//5.通信
int ret;
char buf[size];
pthread_t pthread;
if(0!= pthread_create(&pthread,NULL,send_data,(void *)&sockfd))
{
printf("pthread create failed\n");
return -1;
}
while(1)
{
memset(buf,0,sizeof(buf));
ret = read(sockfd,buf,sizeof(buf));
if(ret < 0)
{
perror("read");
break;
}
else if(ret == 0)
{
printf("client close\n");
break;
}
printf("recv:");
fputs(buf,stdout);
}
//6.关闭套接字
close(sockfd);
return 0;
}
void *send_data(void *argv)
{
int sockfd = (*(int *)argv);
while(1)
{
char buf[size]={0};
printf("send:");
fgets(buf,sizeof(buf),stdin);
if(0 > write(sockfd,buf,sizeof(buf)))
{
perror("write");
break;
}
if(strncmp(buf,"quit",4)==0)
exit(0);
}
}
printf(“-----------------------------我是分隔符--------------------------------------”)
服务器打开文件,客户端创建一个新文件并接收服务器文件的内容
/*===============================================
* 文件名称:server.c
* 创 建 者:
* 创建日期:2023年05月19日
* 描 述:
================================================*/
服务器打开文件,客户端创建一个新文件并接收服务器文件的内容
单向版
类似于下载
#include <stdio.h>
#include "net.h"
int main(int argc, char *argv[])
{
int sockfd, connfd;
if (argc < 2)
{
fprintf(stderr, "Usage: %s <SRVPORT>\n", argv[0]);
return -1;
}
int fd = open("test1.txt", O_WRONLY|O_CREAT|O_TRUNC, 0664);
if (fd < 0)
{
perror("open");
return -1;
}
/*1. 创建套接字*/
if (0 > (sockfd = socket(AF_INET, SOCK_STREAM, 0)))
{
perror("socket");
return -1;
}
printf("socket............\n");
/*2. 绑定本机地址和端口*/
struct sockaddr_in srvaddr;
memset(&srvaddr, 0, sizeof(srvaddr));
srvaddr.sin_family = AF_INET;
srvaddr.sin_port = htons(atoi(argv[1])); //PORT
//srvaddr.sin_addr.s_addr = inet_addr(argv[1]); //IP
srvaddr.sin_addr.s_addr = htonl(INADDR_ANY); //IP:0.0.0.0
if (0 > bind(sockfd, (struct sockaddr*)&srvaddr, sizeof(srvaddr)))
{
perror("bind");
return -1;
}
printf("bind...........\n");
/*3. 设置监听套接字*/
if (0 > listen(sockfd, 5))
{
perror("listen");
return -1;
}
printf("listen...........\n");
/*4. 接收客户端的连接,并生成通信套接字*/
struct sockaddr_in cliaddr;
socklen_t addrlen = sizeof(cliaddr);
if (0 > (connfd = accept(sockfd, (struct sockaddr*)&cliaddr, &addrlen)))
{
perror("accept");
return -1;
}
printf("accept client: %s, %hu\n", inet_ntoa(cliaddr.sin_addr), \
ntohs(cliaddr.sin_port));
/*5. 通信*/
int ret;
char buf[SIZE];
while (1)
{
//循环接收客户端发来的文件内容并写入文件中去
memset(buf, 0, sizeof(buf));
ret = read(connfd, buf, sizeof(buf));
if (ret < 0)
{
perror("recv");
break;
}
else if (0 == ret)
{
printf("client close!\n");
break;
}
if (0 > write(fd, buf, ret))
{
perror("write");
break;
}
}
/*6. 关闭套接字*/
close(connfd);
close(sockfd);
close(fd);
return 0;
}
/*===============================================
* 文件名称:server.c
* 创 建 者:
* 创建日期:2023年05月19日
* 描 述:
================================================*/
#include <stdio.h>
#include "net.h"
int main(int argc, char *argv[])
{
int sockfd, connfd;
if (argc < 3)
{
fprintf(stderr, "Usage: %s <SRVIP> <SRVPORT>\n", argv[0]);
return -1;
}
int fd = open("test.txt", O_RDONLY);
if (fd < 0)
{
perror("open");
return -1;
}
/*1. 创建套接字*/
if (0 > (sockfd = socket(AF_INET, SOCK_STREAM, 0)))
{
perror("socket");
return -1;
}
printf("socket............\n");
/*2. 主动连接服务器*/
struct sockaddr_in srvaddr;
memset(&srvaddr, 0, sizeof(srvaddr));
srvaddr.sin_family = AF_INET;
srvaddr.sin_port = htons(atoi(argv[2])); //PORT
srvaddr.sin_addr.s_addr = inet_addr(argv[1]); //IP
if (0 > connect(sockfd, (struct sockaddr*)&srvaddr, sizeof(srvaddr)))
{
perror("connect");
return -1;
}
printf("connect...........\n");
/*3. 通信*/
int ret;
char buf[SIZE];
while (1)
{
//循环从文件中读取内容并发送给服务器
memset(buf, 0, sizeof(buf));
ret = read(fd, buf, sizeof(buf));
if (ret < 0)
{
perror("read");
break;
}
else if (0 == ret)
{
printf("read file end\n");
break;
}
后面更新双向版本,可以从客户端下载文件到服务器,也可从服务器下载到客户端