当recv()返回值小于等于0时,socket连接断开。但是还需要判断 errno是否等于 EINTR,如果errno == EINTR 则说明recv函数是由于程序接收到信号后返回的,socket连接还是正常的,不应close掉socket连接。
法二:
struct tcp_info info;
int len=sizeof(info);
getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t )&len);
if((infotcpi_state==TCP_ESTABLISHED)) 则说明未断开 else 断开
法三:
若使用了select等系统函数,若远端断开,则select返回1,recv返回0则断开。其他注意事项同法一。
法四:
int keepAlive = 1; // 开启keepalive属性
int keepIdle = 60; // 如该连接在60秒内没有任何数据往来,则进行探测
int keepInterval = 5; // 探测时发包的时间间隔为5 秒
int keepCount = 3; // 探测尝试的次数如果第1次探测包就收到响应了,则后2次的不再发
setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void )&keepAlive, sizeof(keepAlive));
setsockopt(rs, SOL_TCP, TCP_KEEPIDLE, (void)&keepIdle, sizeof(keepIdle));
setsockopt(rs, SOL_TCP, TCP_KEEPINTVL, (void )&keepInterval, sizeof(keepInterval));
setsockopt(rs, SOL_TCP, TCP_KEEPCNT, (void )&keepCount, sizeof(keepCount));
设置后,若断开,则在使用该socket读写时立即失败,并返回ETIMEDOUT错误我有一个使用Java的服务器-客户端程序,我试图用一个端口创建一个ServerSocket,而用不同的端口创建一个客户端Socket,但它们无法相互连接。客户端引发ConnectException。当我将客户端上的套接字更改为与我用于ServerSocket的套接字相同时,它们可以正常工作。
我从此线程Java Networking: Explain InputStream and OutputStream in Socket的asser了解到,如果计算机使用端口创建套接字,则该套接字将绑定到该计算机,那么为什么客户端和服务器需要使用相同的端口来相互连接?
另外,两个应用程序不能使用一台计算机上的同一端口,所以当两个具有相同端口的不同服务器和一台计算机需要通过两个不同的应用程序连接到这两个服务器时,会发生什么情况?
tcp
您需要对推荐答案通信有一些基本的了解。只需谷歌TCP教程。
简而言之,服务器将侦听特定端口。当服务器侦听某个端口时,它将绑定到该端口。一台计算机上只能有一个服务器(或进程)在侦听某个端口。
客户端将连接到计算机并指定要在其上通信的端口。如果服务器正在监听客户端请求的端口,则会发生通信。否则连接无法继续。
因此服务器绑定(或侦听)的端口必须与客户端指定的端口相同。
好了关于客户端和服务器是否需要使用同一端口进行连接?的教程就到这里就结束了,希望趣模板源码网找到的这篇技术文章能帮助到大家,更多技术教程可以在站内搜索。服务器端和客户端都是通过SOCKET来进行通信的,首先产生一个
socket实例,通过这个实例,服务器端调用accept这个方法接收来自客户端发送的信息但是在产生socket实例的时候必须初始化一个端口用来负责接受客户端的请求!
客户端要给服务器发送消息也必须产生一个socket实例,初始化的时候必须指定服务器的IP地址,并且指定服务接收的端口号,这样客户端才能找到服务器要接收的地方,找到地方就可以发送过去了。和你写信一样。找到地址
BufferedReader
in
=
new
BufferedReader(new
InputStreamReader(socketgetInputStream()));
PrintWriter
out
=
new
PrintWriter(socketgetOutputStream());
BufferedReader
wt
=
new
BufferedReader(new
InputStreamReader(Systemin));
这个只是用来获取一个从键盘的一个流传送给服务器端的数据都是通过流来表示的。意思是是键盘输入的一个字节转化成字符流并输出或者写入!首先建议使用一个线程向所有客户端发送消息;
在写一个方法发送消息, 方法里面需要 消息和socket 参数;
Thread tSend= new Thread(SendAll);
private void SendAll()
{
//遍历所有的Socket,调用Send(string msg,Socket socket)方法
//不知道你的Socket放到哪里,如果放到集合就遍历集合挨个调用
}
private void Send(string msg,Socket socket)
{
byte[] buffer = EncodingDefaultGetBytes(msg);
socketSend(buffer);
}所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过"套接字"向网络发出请求或者应答网络请求。\x0d\以J2SDK-13为例,Socket和ServerSocket类库位于javanet包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例, *** 作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。\x0d\重要的Socket API:\x0d\javanetSocket继承于javalangObject,有八个构造器,其方法并不多,下面介绍使用最频繁的三个方法,其它方法大家可以见JDK-13文档。\x0d\ Accept方法用于产生"阻塞",直到接受到一个连接,并且返回一个客户端的Socket对象实例。"阻塞"是一个术语,它使程序运行暂时"停留"在这个地方,直到一个会话产生,然后程序继续;通常"阻塞"是由循环产生的。\x0d\ getInputStream方法获得网络连接输入,同时返回一个InputStream对象实例。\x0d\ getOutputStream方法连接的另一端将得到输入,同时返回一个OutputStream对象实例。\x0d\注意:其中getInputStream和getOutputStream方法均会产生一个IOException,它必须被捕获,因为它们返回的流对象,通常都会被另一个流对象使用。\x0d\2ServerSocket类例子编辑\x0d\\x0d\package comlanbersocket;\x0d\import javaioDataInputStream;\x0d\import javaioDataOutputStream;\x0d\import javaioIOException;\x0d\import javanetServerSocket;\x0d\import javanetSocket;\x0d\public class ServerDemo {\x0d\/\x0d\ 注意:Socket的发送与接收是需要同步进行的,即客户端发送一条信息,服务器必需先接收这条信息,\x0d\ 而后才可以向客户端发送信息,否则将会有运行时出错。\x0d\ @param args\x0d\/\x0d\public static void main(String[] args) {\x0d\ServerSocket ss = null;\x0d\try {\x0d\ss = new ServerSocket(8888);\x0d\//服务器接收到客户端的数据后,创建与此客户端对话的Socket\x0d\Socket socket = ssaccept();\x0d\//用于向客户端发送数据的输出流\x0d\DataOutputStream dos = new DataOutputStream(socketgetOutputStream());\x0d\//用于接收客户端发来的数据的输入流\x0d\DataInputStream dis = new DataInputStream(socketgetInputStream());\x0d\Systemoutprintln("服务器接收到客户端的连接请求:" + disreadUTF());\x0d\//服务器向客户端发送连接成功确认信息\x0d\doswriteUTF("接受连接请求,连接成功!");\x0d\//不需要继续使用此连接时,关闭连接\x0d\socketclose();\x0d\ssclose();\x0d\} catch (IOException e) {\x0d\eprintStackTrace();\x0d\}\x0d\}\x0d\}\x0d\\x0d\3客户端的例子编辑\x0d\package comlanbersocket;\x0d\importjavaioDataInputStream;\x0d\import javaioDataOutputStream;\x0d\importjavaioIOException;\x0d\import javaioOutputStream;\x0d\import javanetSocket;\x0d\import javanetUnknownHostException;\x0d\public class ClientDemo {\x0d\/\x0d\ @param args\x0d\/\x0d\public static void main(String[] args) {\x0d\Socket socket = null;\x0d\try {\x0d\socket = new Socket("localhost",8888);\x0d\//获取输出流,用于客户端向服务器端发送数据\x0d\DataOutputStream dos = new DataOutputStream(socketgetOutputStream());\x0d\//获取输入流,用于接收服务器端发送来的数据\x0d\DataInputStream dis = new DataInputStream(socketgetInputStream());\x0d\//客户端向服务器端发送数据\x0d\doswriteUTF("我是客户端,请求连接!");\x0d\//打印出从服务器端接收到的数据\x0d\Systemoutprintln(disreadUTF());\x0d\//不需要继续使用此连接时,记得关闭哦\x0d\socketclose();\x0d\} catch (UnknownHostException e) {\x0d\eprintStackTrace();\x0d\} catch (IOException e) {\x0d\eprintStackTrace();\x0d\}\x0d\}\x0d\}熟悉socket API熟悉建议先看看socket编程文档链接址:(v=VS85)aspx
般服务端sokcet API调用顺序:
bind() // 设置服务端口
listen() // 等待客户端连接
accept() // 与客户端建立连接
请参考:(v=VS85)aspx
accept函数原型:
SOCKET accept(
__in SOCKET s,
__out struct sockaddr addr,
__inout int addrlen
);
第二参数 addr包含客户端IP址端口认客户端IP端口要注意IP定完全等价于客户端本机端口比:客户端局域网IP址1921681100通ADSL路由连接internet再通internet连接服务端候服务端获客户端IP址能ADSL路由IP获取从客户端读入的字符串
String result = bufferedReaderreadLine(); 这里会阻塞。
你服务器端获取Socket以后 需要另外启动一个线程去处理,你现在是单线程的服务器端设计,当然只能接收一次请求了。
服务器端接收到Socket以后应该启动一个线程
new Thread(new Runable(){
})start();
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)