客户端与服务站《Socket》
2019独角兽企业重金招聘Python工程师标准>>>
// main.m
// 客户端
// Created by DC20160426 on 16/9/5.
// Copyright © 2016年 DC20160426. All rights reserved.
#import <Foundation/Foundation.h>
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
#import <pthread.h>
int fd;
pthread_t threads[2];
void *thread(){
char buf[1024];
ssize_t recvSize;
do {
memset(buf, 0, sizeof(buf));
recvSize =recv(fd, buf, sizeof(buf), 0);
if (recvSize<0) {
NSLog(@"链接断开");
break;
}
printf("从服务端接收到消息%s",buf);
} while (strcmp(buf, "\n")!=0);
printf("%s", buf);
close(fd);
//关闭客户端,只是关闭这个套接字特定的TCP链接
return 0;
}
void *thread1(){
char buf[1024];
do {
printf("请输入内容\n");
memset(buf, 0, sizeof(buf));
scanf("%s",buf);
send(fd, buf, sizeof(buf), 0);
} while (strcmp(buf, "\n")!=0);
return 0;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
//1.domain 2.type 3.protocol
fd=socket(AF_INET, SOCK_STREAM, 0);
BOOL success=(fd !=-1);
int err;
//客户端地址结构体
struct sockaddr_in clientAddr;
if (success) {
NSLog(@"socket成功");
//绑定客户端地址信息
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(@"bind成功");
//创建服务器地址信息
struct sockaddr_in serverAdder;
memset(&serverAdder, 0, sizeof(serverAdder));
serverAdder.sin_len=sizeof(serverAdder);
serverAdder.sin_family=AF_INET;
serverAdder.sin_port=htons(1024);
// serverAdder.sin_addr.s_addr=INADDR_ANY;
serverAdder.sin_addr.s_addr=inet_addr("192.168.3.101");
err=connect(fd, (const struct sockaddr *)&serverAdder, sizeof(serverAdder));
success=(err==0);
if (success) {
NSLog(@"connect成功");
//客户端地址长度
socklen_t addrLen=sizeof(clientAddr);
err=getsockname(fd, (struct sockaddr *restrict)&clientAddr, &addrLen);
success=(err==0);
if (success) {
NSLog(@"本地地址:%s 端口号:%d",inet_ntoa(clientAddr.sin_addr),clientAddr.sin_port);
success = (fd != -1);
if (success) {
pthread_create(&threads[0], NULL, thread, NULL);
pthread_create(&threads[1], NULL, thread1, NULL);
pthread_join(threads[0], NULL);
pthread_join(threads[1], NULL);
}
}
}
}
}
return 0;
}
// main.m
// 服务站
//
// Created by DC20160426 on 16/9/5.
// Copyright © 2016年 DC20160426. All rights reserved.
//
#import <Foundation/Foundation.h>
#include <sys/socket.h>//提供socket函数以及数据结构
#include <netinet/in.h>//定义数据结构
#include <arpa/inet.h>//提供IP地址转换函数
#include <pthread.h>//多线程
//#include <unistd.h>
int clientfd;//客户端套接字
pthread_t thread[2];//线程
void *thread1(){
char buf[1024];
ssize_t recvSize;//接收长度
do {
memset(buf, 0, sizeof(buf));//清理残留
recvSize=recv(clientfd, buf, sizeof(buf), 0);
if (recvSize<0) {
NSLog(@"链接断开!!!");
break;
}
// printf("%s", buf);
NSLog(@"从客户端接收到消息%s",buf);
} while (strcmp(buf,"exit\n")!=0);
printf("%s", buf);
close(clientfd);
//关闭客户端,只是关闭这个套接字特定的TCP链接
return 0;
}
//发送线程
void *thread2(){
char buf[1024];
do {
memset(buf, 0, sizeof(buf));
//获取内容
scanf("%s",buf);
//发送(1.客户端套接字 2.发送内容 3.发送内容大小 4.flag)
send(clientfd, buf, sizeof(buf), 0);
} while (strcmp(buf, "exit\n")!=0);
return 0;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
int sock=socket(AF_INET, SOCK_STREAM, 0);
// 网络协议的套接字类型 ,流,0
BOOL success=(sock!=-1);
//创建一个结构体
struct sockaddr_in addr;//创建一个地址的结构体
int err;
if (success) {
NSLog(@"创建成功");
memset(&addr, 0, sizeof(addr));
addr.sin_len=sizeof(addr);
addr.sin_family=AF_INET;
addr.sin_port=htons(1025);
addr.sin_addr.s_addr=INADDR_ANY;//127.0.0.1
//绑定
err = bind(sock, (const struct sockaddr *)&addr, sizeof(addr));
success=(err==0);//等于0时绑定成功
NSLog(@"%d",err);
}
if (success) {
NSLog(@"bing绑定成功");
err=listen(sock, 5);//第二个参数为等待接收链接的队列的大小
//比如在connect请求过来的时候,完成三次握手后先将连接放在队列中,直到被accept
success = (err==0);//等于0时监听成功
}
if (success) {
NSLog(@"监听成功");
//进行阻塞
while (true) {
//客户端的地址结构体
struct sockaddr_in clientAddr;
//定义一个地址长度变量,接收客户端地址结构体长度
socklen_t addrLen;
addrLen = sizeof(clientAddr);
NSLog(@"等待客户端接入");
//返回值是客户端的套接字
clientfd = accept(sock, (struct sockaddr *)&clientAddr, &addrLen);
NSLog( @"地址:%s 端口号:%d",inet_ntoa(clientAddr.sin_addr),ntohs(clientAddr.sin_port));
success = (clientfd != -1);
if (success) {
// 创建线程 1.线程 2.属性 3.线程函数
pthread_create(&thread[0], NULL, thread1, NULL);
//创建线程
pthread_create(&thread[1], NULL, thread2, NULL);
//以阻塞的方式等待线程指定的函数结束,当函数返回时,资源回收
pthread_join(thread[0], NULL);
pthread_join(thread[1], NULL);
}
}
}
}
return 0;
}
第三方实例
IOS使用Asyncsocket进行socket编程
Socket描述了一个IP、端口对。它简化了程序员的操作,知道对方的IP以及PORT就可以给对方发送消息,再由服务器端来处理发送的这些消息。所以,Socket一定包含了通信的双发,即客户端(Client)与服务端(server)。
1)服务端利用Socket监听端口;
2)客户端发起连接;
3)服务端返回信息,建立连接,开始通信;
4)客户端,服务端断开连接。
1套接字(socket)概念
套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。
应用层通过传输层进行数据通信时,TCP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个 TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。应 用层可以和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。
2 建立socket连接
建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket,另一个运行于服务器端,称为ServerSocket。
套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。
服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。
客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发 给客户端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
4、SOCKET连接与TCP连接
创建Socket连接时,可以指定使用的传输层协议,Socket可以支持不同的传输层协议(TCP或UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接。
5、Socket连接与HTTP连接
由于通常情况下Socket连接就是TCP连接,因此Socket连接一旦建立,通信双方即可开始相互发送数据内容,直到双方连接断开。但在实际网 络应用中,客户端到服务器之间的通信往往需要穿越多个中间节点,例如路由器、网关、防火墙等,大部分防火墙默认会关闭长时间处于非活跃状态的连接而导致 Socket 连接断连,因此需要通过轮询告诉网络,该连接处于活跃状态。
而HTTP连接使用的是“请求—响应”的方式,不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据。
很多情况下,需要服务器端主动向客户端推送
iphone的标准推荐CFNetwork C库编程.但是编程比较烦躁。在其它OS往往用类来封装的对Socket函数的处理。比如MFC的CAsysncSocket.在iphone也有类似于 开源项目.cocoa AsyncSocket库, 官方网站:http://code.google.com/p/cocoaasyncsocket/ 它用来简化 CFnetwork的调用.
一.在项目引入ASyncSocket库
1.下载ASyncSocket库源码
2.把ASyncSocket库源码加入项目:只需要增加RunLoop目录中的AsyncSocket.h、AsyncSocket.m、AsyncUdpSocket.h和AsyncUdpSocket.m四个文件。
3.在项目增加CFNetwork框架
在Framework目录右健,选择Add-->Existing Files... , 选择 CFNetwork.framework
二.TCP客户端
1. 在controller头文件定义AsyncSocket对象
- #import #import "AsyncSocket.h"
- @interface HelloiPhoneViewController : UIViewController { UITextField * textField; AsyncSocket * asyncSocket;}@property (retain, nonatomic) IBOutlet UITextField *textField;- (IBAction) buttonPressed: (id)sender;- (IBAction) textFieldDoneEditing: (id)sender; @end
复制代码
2.在需要联接地方使用connectToHost联接服务器
其中initWithDelegate的参数中self是必须。这个对象指针中的各个Socket响应的函数将被ASyncSocket所调用.
asyncSocket = [[AsyncSocket alloc] initWithDelegate:self];
- NSError *err = nil; if(![asyncSocket connectToHost:host on:port error:&err]) { NSLog(@"Error: %@", err); }
复制代码
3.增加Socket响应事件
因为initWithDelegate把将当前对象传递进去,这样只要在当前对象方法实现相应方法.
4.关于NSData对象
无论SOCKET收发都采用NSData对象.
NSData主要是带一个(id)data指向的数据空间和长度 length.
NSString 转换成NSData 对象
- NSData* xmlData = [@"testdata" dataUsingEncoding:NSUTF8StringEncoding];
复制代码
NSData 转换成NSString对象
NSData * data;
- NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
复制代码
4.发送数据
AsyncSocket writeData 方法来发送数据,它有如下定义
- - (void)writeDataNSData *)data withTimeoutNSTimeInterval)timeout taglong)tag;
复制代码
以下是一个实例语句.
- NSData* aData= [@"test data" dataUsingEncoding: NSUTF8StringEncoding]; [sock writeData:aData withTimeout:-1 tag:1];
复制代码
在onSocket重载函数,有如定义采用是专门用来处理SOCKET的发送数据的:
-(void)onSocket(AsyncSocket *)sock didWriteDataWithTag:(long)tag
- { NSLog(@"thread(%),onSocket:%p didWriteDataWithTag:%d",[[NSThread currentThread] name], sock,tag);}
复制代码
5.接收Socket数据.
在onSocket重载函数,有如定义采用是专门用来处理SOCKET的接收数据的.
- -(void) onSocketAsyncSocket *)sock didReadDataNSData *)data withTaglong)tag
复制代码
在中间将其转换成NSString进行显示.
- NSString* aStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"===%@",aStr); [aStr release];
复制代码
下面是用开源的库Asyncsocket的例子:
- //
- // SocketDemoViewController.h
- // SocketDemo
- //
- // Created by xiang xiva on 10-7-10.
- // Copyright 2010 __MyCompanyName__. All rights reserved.
- //
- #import <UIKit/UIKit.h>
- #import "AsyncSocket.h"
- #define SRV_CONNECTED 0
- #define SRV_CONNECT_SUC 1
- #define SRV_CONNECT_FAIL 2
- #define HOST_IP @"192.168.110.1"
- #define HOST_PORT 8080
- @interface SocketDemoViewController : UIViewController {
- UITextField *inputMsg;
- UILabel *outputMsg;
- AsyncSocket *client;
- }
- @property (nonatomic, retain) AsyncSocket *client;
- @property (nonatomic, retain) IBOutlet UITextField *inputMsg;
- @property (nonatomic, retain) IBOutlet UILabel *outputMsg;
- - (int) connectServer: (NSString *) hostIP port:(int) hostPort;
- - (void) showMessage:(NSString *) msg;
- - (IBAction) sendMsg;
- - (IBAction) reConnect;
- - (IBAction) textFieldDoneEditing:(id)sender;
- - (IBAction) backgroundTouch:(id)sender;
- @end
- //
- // SocketDemoViewController.m
- // SocketDemo
- //
- // Created by xiang xiva on 10-7-10.
- // Copyright 2010 __MyCompanyName__. All rights reserved.
- //
- #import "SocketDemoViewController.h"
- @implementation SocketDemoViewController
- @synthesize inputMsg, outputMsg;
- @synthesize client;
- /*
- // The designated initializer. Override to perform setup that is required before the view is loaded.
- - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
- self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
- if (self) {
- // Custom initialization
- }
- return self;
- }
- */
- /*
- // Implement loadView to create a view hierarchy programmatically, without using a nib.
- - (void)loadView {
- }
- */
- // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- - (void)viewDidLoad {
- //[super viewDidLoad];
- [self connectServer:HOST_IP port:HOST_PORT];
- //监听读取
- }
- // Override to allow orientations other than the default portrait orientation.
- - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
- return YES;
- }
- - (void)didReceiveMemoryWarning {
- // Releases the view if it doesn't have a superview.
- [super didReceiveMemoryWarning];
- // Release any cached data, images, etc that aren't in use.
- }
- - (void)viewDidUnload {
- self.client = nil;
- // Release any retained subviews of the main view.
- // e.g. self.myOutlet = nil;
- }
- - (int) connectServer: (NSString *) hostIP port:(int) hostPort{
- if (client == nil) {
- client = [[AsyncSocket alloc] initWithDelegate:self];
- NSError *err = nil;
- //192.168.110.128
- if (![client connectToHost:hostIP onPort:hostPort error:&err]) {
- NSLog(@"%@ %@", [err code], [err localizedDescription]);
- UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[@"Connection failed to host "
- stringByAppendingString:hostIP]
- message:[[[NSString alloc]initWithFormat:@"%@",[err code]] stringByAppendingString:[err localizedDescription]]
- delegate:self
- cancelButtonTitle:@"OK"
- otherButtonTitles:nil];
- [alert show];
- [alert release];
- //client = nil;
- return SRV_CONNECT_FAIL;
- } else {
- NSLog(@"Conectou!");
- return SRV_CONNECT_SUC;
- }
- }
- else {
- [client readDataWithTimeout:-1 tag:0];
- return SRV_CONNECTED;
- }
- }
- - (IBAction) reConnect{
- int stat = [self connectServer:HOST_IP port:HOST_PORT];
- switch (stat) {
- case SRV_CONNECT_SUC:
- [self showMessage:@"connect success"];
- break;
- case SRV_CONNECTED:
- [self showMessage:@"It's connected,don't agian"];
- break;
- default:
- break;
- }
- }
- - (IBAction) sendMsg{
- NSString *inputMsgStr = self.inputMsg.text;
- NSString * content = [inputMsgStr stringByAppendingString:@"\r\n"];
- NSLog(@"%a",content);
- NSData *data = [content dataUsingEncoding:NSISOLatin1StringEncoding];
- [client writeData:data withTimeout:-1 tag:0];
- //[data release];
- //[content release];
- //[inputMsgStr release];
- //继续监听读取
- //[client readDataWithTimeout:-1 tag:0];
- }
- #pragma mark -
- #pragma mark close Keyboard
- - (IBAction) textFieldDoneEditing:(id)sender{
- [sender resignFirstResponder];
- }
- - (IBAction) backgroundTouch:(id)sender{
- [inputMsg resignFirstResponder];
- }
- #pragma mark socket uitl
- - (void) showMessage:(NSString *) msg{
- UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"Alert!"
- message:msg
- delegate:nil
- cancelButtonTitle:@"OK"
- otherButtonTitles:nil];
- [alert show];
- [alert release];
- }
- #pragma mark socket delegate
- - (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port{
- [client readDataWithTimeout:-1 tag:0];
- }
- - (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
- {
- NSLog(@"Error");
- }
- - (void)onSocketDidDisconnect:(AsyncSocket *)sock
- {
- NSString *msg = @"Sorry this connect is failure";
- [self showMessage:msg];
- [msg release];
- client = nil;
- }
- - (void)onSocketDidSecure:(AsyncSocket *)sock{
- }
- - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
- NSString* aStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
- NSLog(@"Hava received datas is :%@",aStr);
- self.outputMsg.text = aStr;
- [aStr release];
- [client readDataWithTimeout:-1 tag:0];
- }
- #pragma mark dealloc
- - (void)dealloc {
- [client release];
- [inputMsg release];
- [outputMsg release];
- [super dealloc];
- }
- @end
转载于:https://my.oschina.net/6104zhang/blog/745201
客户端与服务站《Socket》相关推荐
- python socket客户端_python 使用socket模拟tcp客户端和tcp服务器端
''' 客户端代码 ''' import socket #创建套接字 tcpClientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREA ...
- Netty服务器部署在Android设备上,接收来自PC客户端的Java Socket客户端发送的JSON数据
Netty服务器部署在Android设备上,接收来自PC客户端的Java Socket客户端发送的数据 一个简单的模型,在Android手机上部署一个Netty写的服务器,绑定端口9000,等待客户端 ...
- nodejs TCP服务器和客户端通信的socket结构
这个结构我们大学时上Unix网络编程的专业课就学过了: nodejs服务器端调用net模块的createServer方法启动一个TCP服务器,这个方法要指定一个回调函数,每当新的客户端发起连接后,回调 ...
- java贪吃蛇客户端服务器_java Socket套接字TCP编程开发服务端和客户端之间的通信 - 贪吃蛇学院-专业IT技术平台...
超级简单,没有太多实质内容的Socket服务端,客户端小程序 先运行server 再运行client OK 服务端代码如下: public class Server { public static v ...
- socket java 客户端_Java基于socket实现的客户端和服务端通信功能完整实例
本文实例讲述了Java基于socket实现的客户端和服务端通信功能.分享给大家供大家参考,具体如下: 以下代码参考马士兵的聊天项目,先运行ChatServer.java实现端口监听,然后再运行Chat ...
- daytime协议的服务器和客户端程序,用Socket套接字实现DAYTIME协议的服务器和客户端程序-20210726002244.doc-原创力文档...
一.设计目的 为了提高同学的自主动手能力,把理论知识运用于实 践中,从实践中更好的领悟所学的知识. 二.题目要求及需求分析 1.网络I/O程序设计:用Socket套接字实现DAYTIME 协 议的服务 ...
- daytime协议的服务器和客户端程序,用Socket套接字实现DAYTIME协议的服务器和客户端程序-20210414073352.docx-原创力文档...
用Socket套接字实现 DAY TIME 协议的服务器和客户端程序 一.设计目的 为了提高同学的自主动手能力,把理论知识运用于实 践中,从实践中更好的领悟所学的知识. 二.题目要求及需求分析 网络I ...
- daytime协议的服务器和客户端程序,用Socket套接字实现DAYTIME协议的服务器和客户端程序.doc...
用Socket套接字实现DAYTIME协议的服务器和客户端程序.doc 一. 设计目的 为了提高同学的自主动手能力,把理论知识运用于实践中,从实践中更好的领悟所学的知识 . 二. 题目要求及需求分析 ...
- daytime协议的服务器和客户端程序,用socket套接字实现daytime协议服务器和客户端程序.doc...
文档介绍: 用socket套接字实现daytime协议服务器和客户端程序.doc一.设计目的为了提高同学的自主动手能力,把理论知识运用于实践中,从实践中更好的领悟所学的知识.二.题目要求及需求分析1. ...
- daytime协议的服务器和客户端程序,用socket套接字实现daytime协议的服务器和客户端程序精编版.doc...
用socket套接字实现daytime协议的服务器和客户端程序精编版.doc 还剩 11页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,喜欢就下载吧,价低环保! 内容要点: ------- ...
最新文章
- 从Java多线程可见性谈Happens-Before原则
- python编写查询_如何用python脚本编写查询
- ubuntu清除无效的右键打开方式
- Python资源大全 屌炸Python库
- PL/Sql快速执行 insert语句的.sql文件
- XSS攻击及解决方案
- 如何在ReactJS中使用FastReport Core Web Report
- python3短信接口
- 天刀显示服务器失败,天涯明月刀手游提示安装失败怎么办 10月16日开服常见问题FAQ...
- 2015年史玉柱演讲实录
- 文科如何晋级计算机职称,职称的档次是怎么确定来的?
- Python基础_Day04
- 浙大 | PTA 习题5-6 使用函数输出水仙花数 (20分)
- php pdf数字签名,用PHP从PDF中检索数字签名信息
- 当知识图谱遇上推荐系统之DKN模型(论文笔记一)
- 网络嗅探 精华版(全)
- 小学数学计算机教案模板,小学数学信息化教学设计模板.doc
- 【大数据开发】Python基础——Python序列
- SVN管理工具Cornerstone之:创建分支、提交合并
- parseObject和fromObject的区别
热门文章
- android:视频录制编写代码一直报非法状态错误,很多时候定位在setVideoEncoder和setAudioEncoder...
- 爪哇国新游记之二十----将数字转换成中国汉字大写形式
- Codeforces Round #159 (Div. 2)
- 《javascript高级程序设计》读书笔记——作用域
- 我碰到的到现在为止,还没有找到比较好的解决方法的sps问题
- 问题查询-批文页面显示别人操作的结果
- CentOS7使用yum安装mysql5.7
- Django 安装使用
- Mac端将本地新项目上传到github
- Kotlin学习笔记(1):标签