您好, , 海量一手媒体资源,专业、正规、高效,为企业提供一站式营销推广服务!
温馨提示
运营小帮手
一站式互联网营销服务平台
  全国免费咨询热线
0755-23071973
运营小帮手
软文发稿
PC端 选择媒体
更方便、更快捷!
查看媒体价格
软文发布、软文代写、百科制作、问答营销、微信营销、微信营销
查看媒体价格
当前位置: 运营小帮手首页 > 新闻中心 > 文章正文

iOS Socket-TCP编程-C语言版

本篇文章为总结使用C语言的api来完成TCP通信的基本功能,如果您对Socket不了解,请先阅读上一篇理论知识:iOS Socket理论知识

如果文章中有任何您认为不正确的或者有疑问的,请联系笔者!

TCP Socket编程

TCP是面向连接的,安全可靠的传输层协议。注意:Socket通信一定有要服务端和客户端。

1.1 TCP Socket客户端

客户端的工作流程:首先调用socket函数创建一个Socket,然后指定服务端的IP地址和端口号,就可以调用sendto将字符串传送给服务器端,并可以调用recvfrom接收服务器端返回的字符串,最后关闭该socket。

笔者这里分成了六步:

  • 第一步:创建socket并配置socket

  • 第二步:调用bind绑定监听ip和端口号

  • 第三步:调用connect连接服务器

  • 第四步:调用getsockname获取套接字信息

  • 第五步:调用send发送消息到服务器端

  • 第六步:调用close关闭socket

这里没有写接收来自服务器端的消息,大家可以自行添加。

1.1.1 客户端的代码实现:

-(void)tcpClient{
//第一步:创建soket
//TCP是基于数据流的,因此参数二使用SOCK_STREAM
interror=-1;
intclientSocketId=socket(AF_INET,SOCK_STREAM,0);
BOOLsuccess=(clientSocketId!=-1);
structsockaddr_inaddr;

//第二步:绑定端口号
if(success){
NSLog(@"clientsocketcreatesuccess");
//初始化
memset(&addr,0,sizeof(addr));
addr.sin_len=sizeof(addr);

//指定协议簇为AF_INET,比如TCP/UDP等
addr.sin_family=AF_INET;

//监听任何ip地址
addr.sin_addr.s_addr=INADDR_ANY;
error=bind(clientSocketId,(conststructsockaddr*)&addr,sizeof(addr));
success=(error==0);
}

if(success){
//p2p
structsockaddr_inpeerAddr;
memset(&peerAddr,0,sizeof(peerAddr));
peerAddr.sin_len=sizeof(peerAddr);
peerAddr.sin_family=AF_INET;
peerAddr.sin_port=htons(1024);

//指定服务端的ip地址,测试时,修改成对应自己服务器的ip
peerAddr.sin_addr.s_addr=inet_addr("192.168.1.107");

socklen_taddrLen;
addrLen=sizeof(peerAddr);
NSLog(@"willbeconnecting");

//第三步:连接服务器
error=connect(clientSocketId,(structsockaddr*)&peerAddr,addrLen);
success=(error==0);

if(success){
//第四步:获取套接字信息
error=getsockname(clientSocketId,(structsockaddr*)&addr,&addrLen);
success=(error==0);

if(success){
NSLog(@"clientconnectsuccess,localaddress:%s,port:%d",
inet_ntoa(addr.sin_addr),
ntohs(addr.sin_port));

//这里只发送10次
intcount=10;
do{
//第五步:发送消息到服务端
send(clientSocketId,"哈哈,server您好!",1024,0);
count--;

//告诉server,客户端退出了
if(count==0){
send(clientSocketId,"exit",1024,0);
}
}while(count>=1);

//第六步:关闭套接字
close(clientSocketId);
}
}else{
NSLog(@"connectfailed");

//第六步:关闭套接字
close(clientSocketId);
}
}
}

1.1.2 客户端的打印日志

2015-12-0618:35:00.385iOS-Socket-C-Version-Client[9726:4256295]clientsocketcreatesuccess
2015-12-0618:35:00.386iOS-Socket-C-Version-Client[9726:4256295]willbeconnecting
2015-12-0618:35:00.507iOS-Socket-C-Version-Client[9726:4256295]clientconnectsuccess,localaddress:192.168.1.100,port:50311

说明连接服务器成功,然后发送了消息到服务器端。

1.2 TCP Socket服务器端

服务器端的工作流程:首先调用socket函数创建一个套接字,然后调用bind函数将其与本机地址以及一个本地端口号绑定,接收到一个客户端时,服务器显示该客户端的IP地址,并将字串返回给客户端。

笔者这里分成了五步:

  • 第一步:创建socket并配置socket

  • 第二步:调用bind绑定服务器本机ip及端口号

  • 第三步:调用listen监听客户端的连接,并指定同时最多可让accept的数量

  • 第四步:调用accept等待客户端的连接

  • 第五步:调用recvfrom接收来自客户端的消息

  • 第六步:调用close关闭socket

1.2.1 服务器端代码实现

-(void)tcpServer{
//第一步:创建socket
interror=-1;

//创建socket套接字
intserverSocketId=socket(AF_INET,SOCK_STREAM,0);
//判断创建socket是否成功
BOOLsuccess=(serverSocketId!=-1);

//第二步:绑定端口号
if(success){
NSLog(@"serversocketcreatesuccess");
//Socketaddress
structsockaddr_inaddr;

//初始化全置为0
memset(&addr,0,sizeof(addr));

//指定socket地址长度
addr.sin_len=sizeof(addr);

//指定网络协议,比如这里使用的是TCP/UDP则指定为AF_INET
addr.sin_family=AF_INET;

//指定端口号
addr.sin_port=htons(1024);

//指定监听的ip,指定为INADDR_ANY时,表示监听所有的ip
addr.sin_addr.s_addr=INADDR_ANY;

//绑定套接字
error=bind(serverSocketId,(conststructsockaddr*)&addr,sizeof(addr));
success=(error==0);
}

//第三步:监听
if(success){
NSLog(@"bindserversocketsuccess");
error=listen(serverSocketId,5);
success=(error==0);
}

if(success){
NSLog(@"listenserversocketsuccess");

while(true){
//p2p
structsockaddr_inpeerAddr;
intpeerSocketId;
socklen_taddrLen=sizeof(peerAddr);

//第四步:等待客户端连接
//服务器端等待从编号为serverSocketId的Socket上接收客户连接请求
peerSocketId=accept(serverSocketId,(structsockaddr*)&peerAddr,&addrLen);
success=(peerSocketId!=-1);

if(success){
NSLog(@"acceptserversocketsuccess,remoteaddress:%s,port:%d",
inet_ntoa(peerAddr.sin_addr),
ntohs(peerAddr.sin_port));
charbuf[1024];
size_tlen=sizeof(buf);

//第五步:接收来自客户端的信息
//当客户端输入exit时才退出
do{
//接收来自客户端的信息
recv(peerSocketId,buf,len,0);
if(strlen(buf)!=0){
NSString*str=[NSStringstringWithCString:bufencoding:NSUTF8StringEncoding];
if(str.length>=1){
NSLog(@"receivedmessagefromclient:%@",str);
}
}
}while(strcmp(buf,"exit")!=0);

NSLog(@"收到exit信号,本次socket通信完毕");

//第六步:关闭socket
close(peerSocketId);
}
}
}
}

1.2.2 服务器端的打印日志

2015-12-0618:34:31.258iOS-Socket-C-Version-Server[39929:2622200]serversocketcreatesuccess
2015-12-0618:34:31.258iOS-Socket-C-Version-Server[39929:2622200]bindserversocketsuccess
2015-12-0618:34:31.259iOS-Socket-C-Version-Server[39929:2622200]listenserversocketsuccess
2015-12-0618:35:00.743iOS-Socket-C-Version-Server[39929:2622200]acceptserversocketsuccess,remoteaddress:192.168.1.100,port:50311
2015-12-0618:35:00.743iOS-Socket-C-Version-Server[39929:2622200]receivedmessagefromclient:哈哈,server您好!
2015-12-0618:35:00.743iOS-Socket-C-Version-Server[39929:2622200]receivedmessagefromclient:哈哈,server您好!
2015-12-0618:35:00.743iOS-Socket-C-Version-Server[39929:2622200]receivedmessagefromclient:哈哈,server您好!
2015-12-0618:35:00.744iOS-Socket-C-Version-Server[39929:2622200]receivedmessagefromclient:哈哈,server您好!
2015-12-0618:35:00.744iOS-Socket-C-Version-Server[39929:2622200]receivedmessagefromclient:哈哈,server您好!
2015-12-0618:35:00.744iOS-Socket-C-Version-Server[39929:2622200]receivedmessagefromclient:哈哈,server您好!
2015-12-0618:35:00.744iOS-Socket-C-Version-Server[39929:2622200]receivedmessagefromclient:哈哈,server您好!
2015-12-0618:35:00.744iOS-Socket-C-Version-Server[39929:2622200]receivedmessagefromclient:哈哈,server您好!
2015-12-0618:35:00.744iOS-Socket-C-Version-Server[39929:2622200]receivedmessagefromclient:哈哈,server您好!
2015-12-0618:35:00.745iOS-Socket-C-Version-Server[39929:2622200]receivedmessagefromclient:哈哈,server您好!
2015-12-0618:35:00.745iOS-Socket-C-Version-Server[39929:2622200]receivedmessagefromclient:exit
2015-12-0618:35:00.745iOS-Socket-C-Version-Server[39929:2622200]收到exit信号,本次socket通信完毕

我们这里打印出了客户端发来的消息,由于上面实现的代码中,只发10次,所以这里只有10条。

源代码

小伙伴们,可以到github下载了:iOS-Socket-C-Version

注意:这里面有两个工程,一个是客户端,一个是服务器端。运行时,先运行服务器端,然后再选择客户端。另外,客户端所指定的服务器端的ip地址一定要修改成您本机对应的ip,不然使用笔者这里的ip就会失败。

关键词:

猜您可能需要的服务: