TCP socket 问题
我的程序是个小demo。服务器端只接受,客户端只发送。
服务器端:
ServerSocket ss = null;
try{
ss = new ServerSocket(2222);
while(true){
Socket socket = ss.accept();
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("客户端说:"+reader.readLine());
}
}catch (Exception e) {
e.printStackTrace();
}finally{
try{
if(ss!=null)
ss.close();
}catch (Exception e) {
}
}
客户端:
Socket socket = null;
try{
socket = new Socket("127.0.0.1", 2222);
System.out.println("连接已建立");
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
while(true){
writer.write("我是客户端..\\r\\n");
writer.flush();
Thread.sleep(3000);
System.out.println("发送完毕...");
}
}catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(socket!=null)
socket.close();
} catch (IOException e) {
}
}
问题是,如果客户端只发一次(就是没有while循环),服务器端是可以收到的,但是如果这样循环发的话,服务器端一次都没有收到。我的debug发现是服务器端一直阻塞在readLine,也就是说客户端发送的东西并没有到达服务器端。但是客户端确实显示循环的"发送完毕"。
[最优解释]
ss = new ServerSocket(1212);
Socket socket = ss.accept();//放在外面
while (true) {
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
System.out.println("客户端说:" + reader.readLine());
}
while (true) {
writer.write("我是客户端..\\r\\n");
writer.newLine();//加上这个:写入一个行分隔符
writer.flush();
Thread.sleep(3000);
System.out.println("发送完毕...");
}
可以到达你的想法了。
[其他解释]
服务器这里在accept方法上阻塞了。 把accept拿到while循环前
[其他解释]
4楼正解 主要是客户端 socket = new Socket("127.0.0.1", 2222);要放到循环体里 每次都要建立新连接 否则服务器会出现connection reset
[其他解释]
这个应该用两个线程来做
[其他解释]
你\n的转义有问题。首先readLine是以\n或是\r为结尾的一行字符串。你是\\r与\\n将其转义 已经不是结束符。并且你这个程序只能读一次。因为客户端第二次发送时。服务器会阻塞在accept这个方法上。
[其他解释]
客户端点ctrl+c结束进程后服务站就会出来内容了。
[其他解释]
没有处理并发问题。我是每次连接都建一个套接字。
import java.net.*;
import java.io.*;
import java.util.*;
public class Server {
public static void main(String[] args){
ServerSocket ss = null;
try{
ss = new ServerSocket(2222);
while(true){
Socket socket = ss.accept();
ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
System.out.print("客户端说:"+(String)input.readObject());
input.close();
}
}catch (Exception e) {
e.printStackTrace();
}finally{
try{
if(ss!=null)
ss.close();
}catch (Exception e) {
}
}
}}
import java.util.*;
public class Client {
public static void main(String[] args){
Socket socket = null;
try{
while(true){
socket = new Socket("127.0.0.1", 2222);
System.out.println("连接已建立");
ObjectOutputStream writer = new ObjectOutputStream(socket.getOutputStream());
writer.writeObject("我是客户端..\\r\\n");
writer.flush();
Thread.sleep(1000);
System.out.println("发送完毕...");
}
}catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(socket!=null)
socket.close();
} catch (IOException e) {
}
}
}}
[其他解释]
第二次发的时候,连接已经建立了啊,不会重用原来建立的socket吗?难道客户端每次发送都要重新socket,发送完后关闭?
[其他解释]
客户端循环发是没问题的,
客户端循环接有问题,因为你每一次循环完后都要accept接受客户端连接...所以尽管你发了那么多,服务器只是一直在等待socket的连接
[其他解释]
楼主存在的问题有两点:
一、如果服务端要循环获取客户端发送的数据需要循环执行readline()
二、客户端writer.write("我是客户端..\\r\\n"); 直接写\r\n即可
服务端:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class TestServer {
public static void main(String[] args) {
ServerSocket ss = null;
try {
ss = new ServerSocket(2222);
while (true) {
Socket socket = ss.accept();
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String line = reader.readLine();
while (line != null) {
System.out.println("客户端说:" + line);
line = reader.readLine();
}
socket.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (ss != null)
ss.close();
} catch (Exception e) {
}
}
}
}
客户端:
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class TestClient {
public static void main(String[] args) {
Socket socket = null;
try {
socket = new Socket("127.0.0.1", 2222);
System.out.println("连接已建立");
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream()));
int count = 1;
while (count < 10) {
writer.write("我是客户端..\r\n");
writer.flush();
Thread.sleep(3000);
count++;
}
System.out.println("发送完毕...");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (socket != null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
[其他解释]
不用重新new Socket,楼主的写法有问题,ss.accept()是个阻塞方法,也就是有客户端跟服务端建立连接(new Socket),该方法才会得到Socket并继续进行下去,楼主这种写法第一次接受到了消息后,accept方法阻塞,等待新Socket注册,所以就打印一次。
[其他解释]
恩,主要是accept的位置,我和多线程服务器端的写法混了,这种写法必须要创建线程处理读写。