搭建客户端与服务器
客户端流程:
- 创建并打开套接字 socket
- 绑定IP地址和端口号 bind
- 请求连接---三次握手 connect
- 收发消息 read/write recv/send
- 关闭套接字 close
服务器流程:
- 创建并打开套接字 socket
- 绑定IP地址和端口号 bind
- 创建监听队列 listen
- 等待并建立连接 accept
- 收发消息 read/write recv/send
- 关闭套接字 close
通过fork父子进程实现:
//客户端
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
//客户端流程:
int main()
{
char servIP[20] = {0};
printf("输入服务器ID:");
gets(servIP);
//1、创建并打开套接字 socket
int sockFd = socket(AF_INET, SOCK_STREAM, 0);
if(sockFd < 0)
{
perror("socket error");
return -1;
}
printf("socket ok!\n");
//2、绑定IP地址和端口号 bind
/*struct sockaddr_in cliAddr = {0};
cliAddr.sin_family = PF_INET;
cliAddr.sin_port = htons(10099);
cliAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int ret = bind(sockFd, (struct sockaddr *)&cliAddr, sizeof(cliAddr));
if(ret < 0)
{
perror("bind error");
close(sockFd);
return -1;
}
printf("bind ok!\n");*/
//3、请求连接---三次握手 connect
struct sockaddr_in servAddr = {0};
servAddr.sin_family = PF_INET;
servAddr.sin_port = htons(10086);
servAddr.sin_addr.s_addr = inet_addr(servIP);
int ret = connect(sockFd, (struct sockaddr *)&servAddr, sizeof(servAddr));
if(ret < 0)
{
perror("connect error!");
close(sockFd);
return -1;
}
printf("connect ok\n");
pid_t pid = fork();
if(pid < 0)
{
perror("fock error");
return -1;
}
//4、收发消息 read/write recv/send
char buf[100] = {0};
if(pid > 0)
{
while(1)
{
memset(buf, 0, sizeof(buf));
// printf("client:\n");
gets(buf);
if(0 == strcmp(buf, "qi"))
{
break;
}
ret = send(sockFd, buf, sizeof(buf), 0);
if(ret < 0)
{
perror("send error!");
close(sockFd);
return -1;
}
}
}
if(pid == 0)
{
while(1)
{
memset(buf, 0, sizeof(buf));
ret = recv(sockFd, buf, sizeof(buf), 0);
if(ret < 0)
{
perror("recv error!");
close(sockFd);
return -1;
}
else if(0 == ret)
{
break;
}
printf("client recv:%s\n", buf);
}
}
//5、关闭套接字 close
close(sockFd);
return 0;
}
//服务器
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
//服务器流程:
int main()
{
//1、创建并打开套接字 socket
int sockFd = socket(AF_INET, SOCK_STREAM, 0);
if(sockFd < 0)
{
perror("socket error!");
return -1;
}
printf("socket ok!\n");
//2、绑定IP地址和端口号 bind
struct sockaddr_in servAddr = {0};
servAddr.sin_family = PF_INET;
servAddr.sin_port = htons(10086);
servAddr.sin_addr.s_addr = inet_addr("0.0.0.0");
int ret = bind(sockFd, (struct sockaddr *)&servAddr, sizeof(servAddr));
if(ret < 0)
{
perror("bind error!");
close(sockFd);
return -1;
}
printf("bind ok!\n");
//3、创建监听队列 listen
ret = listen(sockFd, 12);
if(ret < 0)
{
perror("listen error!");
close(sockFd);
return -1;
}
printf("listening...........\n");
//4、等待并建立连接 accept
struct sockaddr_in cliAddr = {0};
socklen_t len = sizeof(cliAddr);
int connFd = accept(sockFd, (struct sockaddr *)&cliAddr, &len);
if(connFd < 0)
{
perror("accept error!\n");
close(sockFd);
return -1;
}
printf("IP:%s, PORT:%d accept ok!\n", inet_ntoa(cliAddr.sin_addr), htons(cliAddr.sin_port));
pid_t pid = fork();
if(pid < 0)
{
perror("fock error");
return -1;
}
char buf[100] = {0};
//6、收发消息 read/write recv/send
if(pid > 0)
{
while(1)
{
memset(buf, 0, sizeof(buf));
ret = recv(connFd, buf, sizeof(buf), 0);
if(ret < 0)
{
perror("recv error!");
close(sockFd);
close(connFd);
return -1;
}
else if(0 == ret)
{
break;
}
printf("server recv:%s\n", buf);
}
}
if(pid == 0)
{
while(1)
{
memset(buf, 0, sizeof(buf));
// printf("server:\n");
gets(buf);
if(0 == strcmp(buf, "qi"))
{
break;
}
ret = send(connFd, buf, sizeof(buf), 0);
if(ret < 0)
{
perror("send error!");
close(sockFd);
close(connFd);
return -1;
}
}
}
//5、关闭套接字 close
close(sockFd);
close(connFd);
return 0;
}
通过pthread线程实现
//客户端
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>
//客户端流程:
int main()
{
char servIP[20] = {0};
printf("输入服务器ID:");
gets(servIP);
//1、创建并打开套接字 socket
int sockFd = socket(AF_INET, SOCK_STREAM, 0);
if(sockFd < 0)
{
perror("socket error");
return -1;
}
printf("socket ok!\n");
//2、绑定IP地址和端口号 bind
/*struct sockaddr_in cliAddr = {0};
cliAddr.sin_family = PF_INET;
cliAddr.sin_port = htons(10099);
cliAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int ret = bind(sockFd, (struct sockaddr *)&cliAddr, sizeof(cliAddr));
if(ret < 0)
{
perror("bind error");
close(sockFd);
return -1;
}
printf("bind ok!\n");*/
//3、请求连接---三次握手 connect
struct sockaddr_in servAddr = {0};
servAddr.sin_family = PF_INET;
servAddr.sin_port = htons(10086);
servAddr.sin_addr.s_addr = inet_addr(servIP);
int ret = connect(sockFd, (struct sockaddr *)&servAddr, sizeof(servAddr));
if(ret < 0)
{
perror("connect error!");
close(sockFd);
return -1;
}
printf("connect ok\n");
char buf[100] = {0};
int theradFun1(void *arg)
{
while(1)
{
memset(buf, 0, sizeof(buf));
// printf("client:\n");
gets(buf);
if(0 == strcmp(buf, "qi"))
{
break;
}
ret = send(sockFd, buf, sizeof(buf), 0);
if(ret < 0)
{
perror("send error!");
close(sockFd);
return -1;
}
}
}
int theradFun2(void *arg)
{
while(1)
{
memset(buf, 0, sizeof(buf));
ret = recv(sockFd, buf, sizeof(buf), 0);
if(ret < 0)
{
perror("recv error!");
close(sockFd);
return -1;
}
else if(0 == ret)
{
break;
}
printf("client recv:%s\n", buf);
}
}
pthread_t thId1, thId2;
pthread_create(&thId1, NULL, (void *)theradFun1, NULL);
pthread_create(&thId2, NULL, (void *)theradFun2, NULL);
void *th1_val = NULL;
pthread_join(thId1, &th1_val);
void *th2_val = NULL;
pthread_join(thId2, &th2_val);
pthread_detach(thId1);
pthread_detach(thId2);
close(sockFd);
printf("%d", sockFd);
while(1);
return 0;
}
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>
//服务器流程:
int main()
{
//1、创建并打开套接字 socket
int sockFd = socket(AF_INET, SOCK_STREAM, 0);
if(sockFd < 0)
{
perror("socket error!");
return -1;
}
printf("socket ok!\n");
//2、绑定IP地址和端口号 bind
struct sockaddr_in servAddr = {0};
servAddr.sin_family = PF_INET;
servAddr.sin_port = htons(10086);
servAddr.sin_addr.s_addr = inet_addr("0.0.0.0");
int ret = bind(sockFd, (struct sockaddr *)&servAddr, sizeof(servAddr));
if(ret < 0)
{
perror("bind error!");
close(sockFd);
return -1;
}
printf("bind ok!\n");
//3、创建监听队列 listen
ret = listen(sockFd, 12);
if(ret < 0)
{
perror("listen error!");
close(sockFd);
return -1;
}
printf("listening...........\n");
//4、等待并建立连接 accept
struct sockaddr_in cliAddr = {0};
socklen_t len = sizeof(cliAddr);
int connFd = accept(sockFd, (struct sockaddr *)&cliAddr, &len);
if(connFd < 0)
{
perror("accept error!\n");
close(sockFd);
return -1;
}
printf("IP:%s, PORT:%d accept ok!\n", inet_ntoa(cliAddr.sin_addr), htons(cliAddr.sin_port));
char buf[100] = {0};
int theradFun1(void *arg)
{
//6、收发消息 read/write recv/send
while(1)
{
memset(buf, 0, sizeof(buf));
ret = recv(connFd, buf, sizeof(buf), 0);
if(ret < 0)
{
perror("recv error!");
close(sockFd);
close(connFd);
return -1;
}
else if(0 == ret)
{
break;
}
printf("server recv:%s\n", buf);
}
}
int theradFun2(void *arg)
{
while(1)
{
memset(buf, 0, sizeof(buf));
// printf("server:\n");
gets(buf);
if(0 == strcmp(buf, "qi"))
{
break;
}
ret = send(connFd, buf, sizeof(buf), 0);
if(ret < 0)
{
perror("send error!");
close(sockFd);
close(connFd);
return -1;
}
}
}
pthread_t thId1, thId2;
pthread_create(&thId1, NULL, (void *)theradFun1, NULL);
pthread_create(&thId2, NULL, (void *)theradFun2, NULL);
void *th1_val = NULL;
pthread_join(thId1, &th1_val);
void *th2_val = NULL;
pthread_join(thId2, &th2_val);
pthread_detach(thId1);
pthread_detach(thId2);
//5、关闭套接字 close
close(sockFd);
close(connFd);
while(1);
return 0;
}
上传文件
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
//客户端流程:
int main()
{
char servIP[20] = {0};
printf("输入服务器ID:");
gets(servIP);
//1、创建并打开套接字 socket
int sockFd = socket(AF_INET, SOCK_STREAM, 0);
if(sockFd < 0)
{
perror("socket error");
return -1;
}
printf("socket ok!\n");
//2、绑定IP地址和端口号 bind
/*struct sockaddr_in cliAddr = {0};
cliAddr.sin_family = PF_INET;
cliAddr.sin_port = htons(10099);
cliAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int ret = bind(sockFd, (struct sockaddr *)&cliAddr, sizeof(cliAddr));
if(ret < 0)
{
perror("bind error");
close(sockFd);
return -1;
}
printf("bind ok!\n");*/
//3、请求连接---三次握手 connect
struct sockaddr_in servAddr = {0};
servAddr.sin_family = PF_INET;
servAddr.sin_port = htons(10086);
servAddr.sin_addr.s_addr = inet_addr(servIP);
int ret = connect(sockFd, (struct sockaddr *)&servAddr, sizeof(servAddr));
if(ret < 0)
{
perror("connect error!");
close(sockFd);
return -1;
}
printf("connect ok\n");
char filename[20] = {0};
printf("输入要发送的文件名:");
scanf("%s", filename);
ret = send(sockFd, filename, sizeof(filename), 0);
if(ret < 0)
{
perror("recv error!");
close(sockFd);
return -1;
}
int fd = open(filename, O_RDONLY);
if(ret < 0)
{
perror("open error!");
return -1;
}
char buf[1024] = {0};
while(1)
{
ret = read(fd, buf, sizeof(buf));
{
if(ret < 0)
{
perror("read error!");
return -1;
}
if(0 == ret)
{
break;
}
}
ret = send(sockFd, buf, sizeof(buf), 0);
if(ret < 0)
{
perror("send error!");
close(sockFd);
return -1;
}
}
close(fd);
printf("上传文件完毕!\n");
close(sockFd);
return 0;
}
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
//服务器流程:
int main()
{
//1、创建并打开套接字 socket
int sockFd = socket(AF_INET, SOCK_STREAM, 0);
if(sockFd < 0)
{
perror("socket error!");
return -1;
}
printf("socket ok!\n");
//2、绑定IP地址和端口号 bind
struct sockaddr_in servAddr = {0};
servAddr.sin_family = PF_INET;
servAddr.sin_port = htons(10086);
servAddr.sin_addr.s_addr = inet_addr("0.0.0.0");
int ret = bind(sockFd, (struct sockaddr *)&servAddr, sizeof(servAddr));
if(ret < 0)
{
perror("bind error!");
close(sockFd);
return -1;
}
printf("bind ok!\n");
//3、创建监听队列 listen
ret = listen(sockFd, 12);
if(ret < 0)
{
perror("listen error!");
close(sockFd);
return -1;
}
printf("listening...........\n");
//4、等待并建立连接 accept
struct sockaddr_in cliAddr = {0};
socklen_t len = sizeof(cliAddr);
int connFd = accept(sockFd, (struct sockaddr *)&cliAddr, &len);
if(connFd < 0)
{
perror("accept error!\n");
close(sockFd);
return -1;
}
printf("IP:%s, PORT:%d accept ok!\n", inet_ntoa(cliAddr.sin_addr), htons(cliAddr.sin_port));
char filename[20] = {0};
char suffix[5] = {"(1)"};
char buf[1024] = {0};
ret = recv(connFd, filename, sizeof(filename), 0);
if(ret < 0)
{
perror("recv error!");
close(connFd);
close(sockFd);
return -1;
}
strcat(filename, suffix);
int fd = open(filename, O_RDWR | O_CREAT, 0666);
if(fd < 0)
{
perror("open error!");
return -1;
}
ret = recv(connFd, buf, sizeof(buf), 0);
if(ret < 0)
{
perror("recv error!");
return -1;
}
ret = write(fd, buf, sizeof(buf));
if(ret < 0)
{
perror("write error!");
return -1;
}
close(fd);
printf("接受文件完毕!\n");
close(sockFd);
close(connFd);
return 0;
}