Android上实现TCP客户端
那么,今天我们就来讲讲tcp之服务端的封装吧。我已经将tcp服务端封装成了一个类—TcpServer,下面就来讲讲它的使用吧。
今天涉及内容:
先来波效果图
在 tcp服务端 建立 ServerSocket 的时候,我们通常是这样的:
其实以上方法调用的是
其中涉及到的参数:
鉴于tcp服务端 ServerSocket 一般运行在 "本机" 上,则快速初始化 ServerSocket 运用上面的方法:
意思是建立的ServerSocket IP地址为本机,可容纳socket个数为 50 。
在理解了 ServerSocket 初始化问题后,让我们来看看封装类TcpServer的几个主要方法:
TcpServer 主要是在 java 上运行,所以就让我们在 Androidstudio 上模拟下在 Java 中运行tcp服务端的场景:
这里涉及到的两个类 SocketConfig 和 SocketHelper 和之前的一样,大家可以参考文章 Android上实现TCP客户端 中与之相关的介绍,这里就不赘述了。
tcp服务端主要容易出现以下两个问题:
对于第一个问题,这里需要强调的是 TcpServer 的接收方法 receiveMessage(String charsetName) 是以 (result = bufferedReader.readLine()) != null 做判断读取 stream 的,所以客户端向 TcpServer 发送消息时,需要在结尾加上\n,这样 TcpServer 的receiveMessage(String charsetName)方法才能将传过来的数据接收完整。
对于第二个问题,则需要客户端与服务端设置相同的字符集以保证数据不乱码。
封装类 TcpServer 源码如下:
最简单的那种?我给你写一个=,=//服务器
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
main()
{
//创建套接字
int serverSocket= socket(AF_INET,SOCK_STREAM,0)
struct sockaddr_in server_addr
struct sockaddr_in clientAddr
int addr_len = sizeof(clientAddr)
int client
char buffer[200]
//创建地址
bzero(&server_addr,sizeof(server_addr))
server_addr.sin_family =AF_INET
server_addr.sin_port = htons(5555)
server_addr.sin_addr.s_addr = htonl(INADDR_ANY)
//绑定
bind(serverSocket,(struct sockaddr *)&server_addr,sizeof(server_addr))
//帧听
listen(serverSocket,5)
printf("客户端发过来的 :\n")
//接收
client=accept(serverSocket,(sockaddr *)&clientAddr,(socklen_t*)&addr_len)
printf("客户端发过来的 :\n")
while(1)
{
if(recv(client,buffer,sizeof(buffer),0)>0)
printf("客户端发过来的 : %s\n",buffer)
}
return 0
}
//客户端
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
main()
{
struct sockaddr_in serverAddr
int clientSocket=socket(AF_INET,SOCK_STREAM,0)
char sendbuf[200]
//创建地址信息
serverAddr.sin_family=AF_INET
serverAddr.sin_port=htons(5555)
serverAddr.sin_addr.s_addr=inet_addr("127.0.0.1")
//连接服务器
connect(clientSocket,(sockaddr*)&serverAddr,sizeof(serverAddr))
printf("连接目标主机中.....\n连接完成......\n")
//
while(1)
{
printf("请输入发给服务器的数据 : ")
scanf("%s",sendbuf)
//strcmp函数作用,比较两个东东(按ASCII值大小相比较),相同就==0。
if(strcmp(sendbuf,"x")==0)
break
send(clientSocket,sendbuf,sizeof(sendbuf),0)
}
close(clientSocket)
return 0
}
int client() { system("color 0a")//修改DOS窗口颜色,是其成0A。 WORD wVersion=MAKEWORD(1,1) WSADATA wsData int nResult= WSAStartup(wVersion,&wsData)//启动WINSOCKET if(nResult !=0) { printf("启动Winsock失败!\n") } SOCKET sc=socket(AF_INET,SOCK_STREAM,IPPROTO_IP)//创建套接字 if(sc==INVALID_SOCKET) { printf("创建套接字失败!\n") } SOCKADDR_IN addrScaddrSc.sin_family=AF_INET addrSc.sin_port=htons(portNum)//保证字节顺序 char IP[20]again: printf("请输入服务器的IP地址:")gets(IP) if( -1==inet_addr(IP) ) //循环检测IP地址是否合法 { printf("IP地址错误!\n")goto again} addrSc.sin_addr.S_un.S_addr=inet_addr(IP) int b=0while(b<5) //检测5次,如果服务器在此时间内启动,则进行连接 { nResult=connect(sc,(SOCKADDR*)&addrSc,sizeof(SOCKADDR))//套接字连接 Sleep((DWORD)100)//延时1秒 if(nResult==SOCKET_ERROR) { printf(" %d 次连接失败!\n",b+1)} else breakb++} if(nResult==SOCKET_ERROR) { printf("登陆超时,请重新登陆!\n")goto again} char *buf="连接成功!"//向服务端验证连接成功 nResult=send(sc,buf,strlen(buf)+1,0) if(nResult==SOCKET_ERROR) { printf("5.套接字发送数据失败!\n")return 0} char mess[M]nResult =recv(sc,mess,strlen(mess),0)//接受服务端的连接验证信息 if(nResult == -1 ) //判断服务端是否关闭 { printf("\n服务端已断开\n")system("pause")exit(0)} printf("%s\n",mess)tianle: system("cls")//清屏 puts("\n\n")puts(" * * ")puts(" * 欢·迎·使·用·局·域·网·文·件·发·送·工·具 *")puts(" * (客 户 端) * ")puts(" * * ")puts(" * * ")puts(" * 请等待服务端的相应操作 * ")puts(" * * ")puts(" * * ")puts(" * 天乐软件工作室制作 * ")puts(" * 2008-3-1 * ")puts(" * 版权所有★欢迎传播 * ")puts("全屏(退出全屏)操作请按:ALT+ENTER\n")char rMess[100]nResult=recv(sc,rMess,strlen(rMess),0)//接收服务端发来的操作请求 if(nResult==-1) //判断服务端是否关闭 { printf("\n服务端已断开\n")system("pause")goto tianle} printf("%s\n",rMess)char chchar str[100]gets(str)ch=str[0]while( ch!='Y' &&ch!='y' &&ch!='N' &&ch!='n' ) //处理客户端的错误输入 { printf("输入有误,请重新输入(Y/N):")gets(str)ch=str[0]} send(sc,&ch,sizeof(char),0)//向服务端反馈选择,并执行相应操作 if(strcmp(rMess,"服务端向你传送文件,是否接受(Y/N):")==0 &&(ch=='Y' || ch=='y') ) { receiveFile(sc)} if(strcmp(rMess,"服务端向你发起聊天,是否接受(Y/N):")==0 &&(ch=='Y' || ch=='y') ) { chatting_client(sc)} if(ch=='N' || ch=='n') { printf("你拒绝了!\n")system("pause")} system("cls")goto tianlenResult=closesocket(sc)//关闭套接字 if(nResult==SOCKET_ERROR) { printf("8.关闭套接字失败!\n")return 0} }满意请采纳
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)