socket服务端与客户端
———————————————服务端———————————————
引入框架
#include <sys/socket.h>//提供socket函数以及数据结构
#include <netinet/in.h>//定义数据结构
#include <arpa/inet.h>//提供IP地址转换函数
服务端顺序:1.socket(套接字)->2.bind(绑定)->3.listen(监听)->4.while(true)accept(阻塞,等待客户端联络,接收)->5.recv(接收)->6.close(关闭)
< 1 >创建套接字
1.协议 2.socket类型 3.协议—0
int fd=socket(AF_INET,SOCK_STREAM , 0);
NSLog(@„%d",fd);
printf("%d",fd);
//条件
BOOL success=(fd !=-1);
创建一个结构体(用来储存地址信息)
struct sockaddr_in addr;
错误信息
int err;
< 2 >绑定服务端的一些设置
if(success)
{NSLog(@"socket成功");
创建初始化信息
类似((alloc)init)
memset(&addr, 0, sizeof(addr));
1.地址 2.地址初始化 3.容量
长度
addr.sin_len=sizeof(addr);
家族
addr.sin_family=AF_INET;
Ipv4
端口号(网络端口的一种形式)
addr.sin_port=htons(1024);
addr.sin_addr.s_addr=INADDR_ANY;
127.0.0.1
进行绑定bind
bind(<#int#>, <#const struct sockaddr *#>, <#socklen_t#>)
bind(fd, (const struct sockaddr *)&addr, sizeof(addr));
参数:,地址转化,
用err去接收
err=bind(fd, (const struct sockaddr *)&addr, sizeof(addr));
(err==0)绑定成功
success=(err==0);}
是否绑定成功
if(success)
{NSLog(@"bind成功");
< 3 >接听
connect请求过来时候,完成三次握手
err=listen(fd, 5);
1.套接字 2.等待接受连接的对队列的大小
(err==0)监听成功
success=(err==0);}
if(success)
{NSLog(@"listen成功");
< 4 >进行阻塞
while (true)
{
客户端的地址结构体
struct sockaddr_in clientAddr;
定义一个地址长度的变量,接收客户端地址结构体长度
socklen_t addrLen;
addrLen=sizeof(clientAddr);
NSLog(@"等待客户端连入");
------------------------终端输入以下内容-----------------------
------------------- nc - 4 127.0.0.1 1024 ------------------
------------------------以下内容才会输出-----------------------
< 5 >进行接收
accept(<#int#>, <#struct sockaddr *restrict#>, <#socklen_t *restrict#>);
accept(fd, (struct sockaddr *)&clientAddr, &addrLen);
1.套接字
返回值是客户端的套接字
int clientfd=accept(fd, (struct sockaddr *)&clientAddr, &addrLen);
NSLog(@"地址:%s , 端口号:%d",inet_ntoa(clientAddr.sin_addr),ntohs(clientAddr.sin_port));
success=(clientfd!=-1);
if (success)
{char buf[1024];
接收长度
ssize_t receSize;
添加do-while循环
do {
处理残留
memset(buf, 0, sizeof(buf));
接收信息的长度
receSize=recv(clientfd, buf, sizeof(buf), 0);
断开连接
if(receSize<0)
{NSLog(@"~再见");
break;}
printf(„从客户端收到消息:%s\n",buf);}
while (1);//无限循环
while (strcmp(buf, "exit\n")!=0);
关闭客户端:只是关闭这个套接字特定的TCP的连接
close(clientfd);}}}
return 0;}
—————————————服务端(多线程)——————————————
#include <pthread.h>//多线程
pthread_t thread[2];
int clientfd;
接受线程
void *thread1()
{char buf[1024];
接收长度
ssize_t receSize;
添加do-while循环
do {
处理残留
memset(buf, 0, sizeof(buf));
接收信息的长度
receSize=recv(clientfd, buf, sizeof(buf), 0);
断开连接
if(receSize<0)
{NSLog(@„~再见");
break;}
printf(„从客户端收到消息:%s\n",buf);}
// while (1);//无限循环
while (strcmp(buf, "exit\n")!=0);
关闭客户端:只是关闭这个套接字特定的TCP的连接
close(clientfd);
return 0;}
发送线程
void *thread2()
{char buf[1024];
memset(buf, 0, sizeof(buf));
do{
处理残留
memset(buf, 0, sizeof(buf));
获取内容
scanf("%s\n",buf);
发送
send(clientfd, buf, sizeof(buf), 0);
客户端套接字,发送内容,发送内容大小,flag
} while (strcmp(buf, "exit\n")!=0);
close(clientfd);
return 0;}
创建线程
pthread_create(&thread[0], NULL, thread1, NULL);
1.线程 2.属性 3.线程函数
pthread_create(&thread[1], NULL, thread2, NULL);
以阻塞的方式等待线程指定的函数结束。当函数返回时,资源回收
pthread_join(thread[0], NULL);
创建线程
pthread_join(thread[1], NULL);}
———————————————客户端———————————————
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main() {
客户端顺序:socket-->bind-->connect-->sebd/recv-->close
int fd=socket(AF_INET, SOCK_STREAM, 0);
1.domain(定义域) 2.type 3.protocol
BOOL success=(fd!=-1);
int err;
客户端地址
struct sockaddr_in clientAddr;
if (success){
NSLog(@"套接字创建成功");
memset(&clientAddr, 0, sizeof(clientAddr));
clientAddr.sin_len=sizeof(clientAddr);
clientAddr.sin_family=AF_INET;
clientAddr.sin_addr.s_addr=INADDR_ANY;
err=bind(fd, (const struct sockaddr *)&clientAddr, sizeof(clientAddr));
success=(err==0);}
if (success)
{NSLog(@"绑定成功");
创建服务器地址信息
struct sockaddr_in serverAddr;
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_len=sizeof(serverAddr);
serverAddr.sin_port=htons(1024);
本地测试
serverAddr.sin_addr.s_addr=inet_addr("127.0.0.1");
err=connect(fd, (const struct sockaddr *)&serverAddr, sizeof(serverAddr));
success=(err==0);}
if (success){NSLog(@"连接成功");
获取服务端信息
socklen_t addrLen=sizeof(clientAddr);
getsockname可以正确获得当前正在通信的socket的IP,端口等信息
err=getsockname(fd, (struct sockaddr *)&clientAddr, &addrLen);
success=(err==0);
if (success){
NSLog(@"地址:%s,端口号:%d",inet_ntoa(clientAddr.sin_addr),ntohs(clientAddr.sin_port));
发送消息
char buf[1024];
do{printf("请输入内容:");
scanf("%s",buf);
send(fd, buf, sizeof(buf), 0);
} while (1);}
return 0;}
//创建线程
pthread_create(&thread[0], NULL, thread1, NULL);
1.线程 2.属性 3.线程函数
pthread_create(&thread[1], NULL, thread2, NULL);
以阻塞的方式等待线程指定的函数结束。当函数返回时,资源回收
pthread_join(thread[0], NULL);
pthread_join(thread[1], NULL);
—————————————客户端(多线程)——————————————
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
pthread_t thread[2];
int fd;
接受线程
void *thread1(){
char buf[1024];
接收长度
ssize_t receSize;
添加do-while循环
do {
处理残留
memset(buf, 0, sizeof(buf));
接收信息的长度
receSize=recv(fd, buf, sizeof(buf), 0);
断开连接
if(receSize<0)
{NSLog(@"~再见");break;}
scanf("%s",buf);
printf("从服务端收到消息:%s\n",buf);}
// while (1);//无限循环
while (strcmp(buf, "exit\n")!=0);
关闭客户端:只是关闭这个套接字特定的TCP的连接
close(fd);
return 0;}
void *thread2()
{char buf[1024];
do{printf("请输入内容:\n");
memset(buf, 0, sizeof(buf));
scanf("%s",buf);
send(fd, buf, sizeof(buf), 0);} while (1);
return 0;}
创建线程
pthread_create(&thread[0], NULL, thread1, NULL);
1.线程 2.属性 3.线程函数
以阻塞的方式等待线程指定的函数结束。当函数返回时,资源回收
pthread_create(&thread[1], NULL, thread2, NULL);
pthread_join(thread[0], NULL);
pthread_join(thread[1], NULL);