Socket(一)笔记 C实现
引入C头文件
#import <sys/types.h>
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>```
- 初始化Socket并连接服务器
pragma mark -- 初始化Socket方法
static int CreateClinetSocket()
{
int ClinetSocket = 0;
//创建一个socket,返回值为Int。(注scoket其实就是Int类型)
//第一个参数addressFamily IPv4(AF_INET) 或 IPv6(AF_INET6)。
//第二个参数 type 表示 socket 的类型,通常是流stream(SOCK_STREAM) 或数据报文datagram(SOCK_DGRAM)
//第三个参数 protocol 参数通常设置为0,以便让系统自动为选择我们合适的协议,对于 stream socket 来说会是 TCP 协议(IPPROTO_TCP),而对于 datagram来说会是 UDP 协议(IPPROTO_UDP)。
ClinetSocket = socket(AF_INET, SOCK_STREAM, 0);
return ClinetSocket;
}
- 连接服务器
pragma mark -- 连接到服务器
static int ConnectionToServer(int client_socket,const char * server_ip,unsigned short port)
{
//生成一个sockaddr_in类型结构体
struct sockaddr_in sAddr={0};
sAddr.sin_len=sizeof(sAddr);
//设置IPv4
sAddr.sin_family=AF_INET;
//inet_aton是一个改进的方法来将一个字符串IP地址转换为一个32位的网络序列IP地址
//如果这个函数成功,函数的返回值非零,如果输入地址不正确则会返回零。
inet_aton(server_ip, &sAddr.sin_addr);
//htons是将整型变量从主机字节顺序转变成网络字节顺序,赋值端口号
sAddr.sin_port=htons(port);
//用scoket和服务端地址,发起连接。
//客户端向特定网络地址的服务器发送连接请求,连接成功返回0,失败返回 -1。
//注意:该接口调用会阻塞当前线程,直到服务器返回。
if (connect(client_socket, (struct sockaddr *)&sAddr, sizeof(sAddr))==0) {
return client_socket;
}
return 0;
}
- (void)initScoket
{
//每次连接前,先断开连接
if (_clientScoket != 0) {
[self disConnect];
_clientScoket = 0;
}
//创建客户端socket
_clientScoket = CreateClinetSocket();
//服务器Ip
const char * server_ip="127.0.0.1";
//服务器端口
short server_port=6969;
//等于0说明连接失败
if (ConnectionToServer(_clientScoket,server_ip, server_port)==0) {
printf("Connect to server error\n");
return ;
}
//走到这说明连接成功
printf("Connect to server ok\n");
}
- 往服务器发消息
pragma mark -- 发送消息
- (void)sendMsg:(NSString *)msg
{
// 转成C字符串
const char *send_Message = [msg UTF8String];
// 调用send方法 发送字符串到服务器
send(self.clientScoket,send_Message,strlen(send_Message)+1,0);
}
- 开辟一个常驻线程 调用一个死循环来一直监听并接受服务器发来的消息
pragma mark -- 收到消息
-
(void)recieveAction{
// 死循环一直调用来收消息
while (1) {
// 开辟一块内存 用来接收 或者缓冲消息
char recv_Message[1024] = {0};
recv(self.clientScoket, recv_Message, sizeof(recv_Message), 0);
printf("%s\n",recv_Message);
}
}
- 断开连接
pragma mark -- 断开连接
- (void)disConnect
{
//关闭连接
close(self.clientScoket);
}
###服务器
使用node服务器实现
var net = require('net');
var HOST = '127.0.0.1';
var PORT = 6969;
// 创建一个TCP服务器实例,调用listen函数开始监听指定端口
// 传入net.createServer()的回调函数将作为”connection“事件的处理函数
// 在每一个“connection”事件中,该回调函数接收到的socket对象是唯一的
net.createServer(function(sock) {
// 我们获得一个连接 - 该连接自动关联一个socket对象
console.log('CONNECTED: ' +
sock.remoteAddress + ':' + sock.remotePort);
sock.write('服务端发出:连接成功');
// 为这个socket实例添加一个"data"事件处理函数
sock.on('data', function(data) {
console.log('DATA ' + sock.remoteAddress + ': ' + data);
// 回发该数据,客户端将收到来自服务端的数据
sock.write('You said "' + data + '"');
});
// 为这个socket实例添加一个"close"事件处理函数
sock.on('close', function(data) {
console.log('CLOSED: ' +
sock.remoteAddress + ' ' + sock.remotePort);
});
}).listen(PORT, HOST);
console.log('Server listening on ' + HOST +':'+ PORT); ```
- 收到消息后代理发出去
if (self.delegate && [self.delegate respondsToSelector:@selector(receiveMessage:)]) {
[self.delegate receiveMessage:[NSString stringWithFormat:@"%s",recv_Message]];
}
- 接收
- (void)receiveMessage:(NSString *)message{
NSLog(@"收到的消息为%@",message);
dispatch_async(dispatch_get_main_queue(), ^{
self.receiveMessageTF.text = message;
});
}
搭建一个简单的界面测试一下
- 终端启动服务端
node Server.js```
发送消息
