一、大概框架:
监听端:
1. 创建 socket
2. 创建并初始化 监听端sockaddr
3. 绑定监听端 sockaddr
4. 设置监听个数
5. 创建发送端sockaddr
6. 接受发送端(没有发送端连接,会阻塞)
7. 开始 接收发送数据
8. 关闭连接
发送端:
1. 创建 socket
2. 创建并初始化 监听端sockaddr
3. 连接 监听端socket
4. 开始 接收发送数据
5. 关闭连接
不同之处:
监听端有 绑定,监听,接受操作
发送端有 连接操作
二、代码:
监听端代码:
socketservice.c
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#define MAXLINE 128
#define SERV_PORT 8001
int main(int argc, char *argv[])
{
char buf[MAXLINE];
// 1. 创建 socket(参数:协议族ipv4, socket连接类型, 协议类型)
int socketfd = socket(AF_INET, SOCK_STREAM, 0);
// 2. 创建并初始化 监听端sockaddr(协议族, ip, port端口号)
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
inet_pton(AF_INET, "0.0.0.0", &servaddr.sin_addr);
servaddr.sin_port = htons(SERV_PORT);
// 3. 绑定监听端sockaddr(参数:监听端 socketfd, 监听端socketaddr指针, 监听端socketaddr字节数))
bind(socketfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
// 4. 设置监听个数
listen(socketfd, 5);
// 5. 创建发送端sockaddr
struct sockaddr_in clientaddr;
int n = sizeof(clientaddr);
// 6. 接受发送端(没有发送端连接,会阻塞)
// 参数: 监听端 socketfd, 发送端sockaddr指针,发送端sockaddr字节数指针
// 返回 发送端socketfd,
//注意:这里第三个参数用的指针,为了方便返回字节数
int clientfd = accept(socketfd, (struct sockaddr *)&clientaddr, (socklen_t *)&n);
printf("开始连接发送端%d\n", clientfd);
// 7. 开始 接收发送数据
char sendbuf[] = "sockservicerecive\n";
while(1){
// 读取数据|参数:发送端socketfd, 数据指针,数据字节数
int n = read(clientfd, buf, MAXLINE);
if(n == 0){
printf("client:%d disconnect...\n", socketfd);
break;
}else{
printf("%s\n", buf);
// 发送数据|参数:发送端socketfd, 数据指针,数据字节数
write(clientfd, sendbuf, strlen(sendbuf));
}
}
// 8. 关闭连接
close(socketfd);
return 0;
}
发送端代码:
socketclient.c
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<pthread.h>
#define MAXLINE 128
#define SERV_PORT 8001
// 读函数
void* readPthread(void *arg)
{
// 设置自动回收
pthread_detach(pthread_self());
int socketfd = (int)arg;
char buf[MAXLINE];
while(1){
// 读取监听端发送;过来的数据
//参数:监听端socketfd, 数据指针,数据字节数
int n = read(socketfd, buf, MAXLINE);
if(n == 0){
printf("disconnect...\n");
break;
}else{
printf("%s\n", buf);
}
}
close(socketfd);
return (void *)0;
}
int main(int argc, char * argv[])
{
// struct SOCKADDR_IN servaddr;
char buf[MAXLINE];
// 1. 创建 socket(参数:协议族ipv4, socket连接类型, 协议类型)
int socketfd = socket(AF_INET, SOCK_STREAM, 0);
// 2. 创建并初始化 监听端 sockaddr(协议族, ip, port端口号)
struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET; //协议族 = ipv4
inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
servaddr.sin_port = htons(SERV_PORT);
// 3. 绑定监听端 sockaddr(参数:监听端 socketfd, 监听端socketaddr指针, 监听端socketaddr字节数))
connect(socketfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
// 这里启动一个线程执行,读操作
pthread_t thid;
pthread_create(&thid, NULL, readPthread, (void *)socketfd);
// 写数据
while(fgets(buf, MAXLINE, stdin) != NULL){
// 发送数据|参数:监听端socketfd, 数据指针,数据字节数
write(socketfd, buf, strlen(buf));
}
close(socketfd);
return 0;
}
[注]:由于 pthread库 不是 linux的标准库,直接编译回报错,在后面加上 -lpthread即可
gcc ./socketclient.c -o socketclient -lpthread