socket服务端与客户端

Socket编程详解
本文详细介绍了Socket编程的基础知识,包括服务端与客户端的建立过程、多线程处理方式及具体实现步骤。通过实例演示了如何使用Socket进行网络通信。

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);

转载于:https://my.oschina.net/shaosimingbaifeng/blog/742733

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值