首先,这是我的服务器。请看这部分
if(clients.size() == 2){
sendStartSignal();
break;
}
在上面的部分中,当至少两个客户端连接到服务器时,我发送一个启动信号“start”字符串。
服务器代码从这里开始......
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <iostream>
#include <pthread.h>
#include <vector>
#include <sys/fcntl.h>
using namespace std;
void * handle_client(void * ptr);
void sendStartSignal();
struct thdata{
int client_no;
};
vector<pthread_t *> clients;
vector<int> client_nos;
int main(int argc, char **argv)
{
struct sockaddr_in server_addr,client_addr;
socklen_t clientlen = sizeof(client_addr);
int option, port, reuse;
int server, client;
int nread;
// setup default arguments
port = 3000;
// process command line options using getopt()
// see "man 3 getopt"
while ((option = getopt(argc,argv,"p:")) != -1) {
switch (option) {
case 'p':
port = atoi(optarg);
break;
default:
cout << "server [-p port]" << endl;
exit(EXIT_FAILURE);
}
}
// setup socket address structure
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = INADDR_ANY;
// create socket
server = socket(PF_INET,SOCK_STREAM,0);
if (!server) {
perror("socket");
exit(-1);
}
// set socket to immediately reuse port when the application closes
reuse = 1;
if (setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) {
perror("setsockopt");
exit(-1);
}
// call bind to associate the socket with our local address and
// port
if (bind(server,(const struct sockaddr *)&server_addr,sizeof(server_addr)) < 0) {
perror("bind");
exit(-1);
}
// convert the socket to listen for incoming connections
if (listen(server,SOMAXCONN) < 0) {
perror("listen");
exit(-1);
}
// accept clients
while ((client = accept(server,(struct sockaddr *)&client_addr,&clientlen)) > 0) {
//make the clients non blocking
fcntl(client, F_SETFL, O_NONBLOCK);
pthread_t* th = new pthread_t;
thdata* data = new thdata;
data->client_no = client;
clients.push_back(th);
client_nos.push_back(client);
pthread_create(th, NULL, &handle_client, (void *) data);
if(clients.size() == 2){
sendStartSignal();
break;
}
}
for(int i=0;i<clients.size();i++){
pthread_join(*clients[i], NULL);
}
}
void sendStartSignal(){
char *buf;
int buflen;
int nread;
// allocate buffer
buflen = 1024;
buf = new char[buflen+1];
buf[0] = 's';
buf[1] = 't';
buf[2] = 'a';
buf[3] = 'r';
buf[4] = 't';
buf[5] = 0;
for(int i = 0;i<clients.size();i++) {
send(client_nos[i], buf, 6, 0);
}
}
void * handle_client(void * ptr){
thdata * data = (thdata*) ptr;
char *buf;
int buflen;
int nread;
// allocate buffer
buflen = 1024;
buf = new char[buflen+1];
int client_no = data->client_no;
// loop to handle all requests
while (1) {
// read a request
memset(buf,0,buflen);
nread = recv(client_no,buf,buflen,0);
if(nread >= 0){
if(nread == 0) {
int index_to_delete = -1;
for(int i=0;i<client_nos.size();i++){
if(client_nos[i] == client_no){
index_to_delete = 0;
break;
}
}
clients.erase(clients.begin() + index_to_delete);
client_nos.erase(client_nos.begin() + index_to_delete);
break;
}
for(int i = 0;i<clients.size();i++) {
if (client_nos[i] != client_no){
send(client_nos[i], buf, nread, 0);
}
}
}
}
}
现在,这是我在java中的客户端
请看这部分......
public static void handle_read(){
while(true){
try{
String line = r.readLine();
System.out.println(line);
}
catch(Exception e){
System.err.println(e);
}
}
}
在上面的部分中,它是一个只读取来自服务器的传入消息的线程。现在,我的问题是,正如您在服务器代码中看到的那样,只要建立两个连接,就会向客户端发送“start”信号....现在,只要两个客户端连接到客户端,客户端就不会打印启动server ...它只在我向服务器发送一些消息后打印“start”。为什么会这样?
客户从这里开始......
import java.io.*;
import java.net.*;
import java.util.*;
public class Client
{
public static BufferedReader r;
public static PrintWriter w;
public static void main(String[] args){
try
{
Socket s = new Socket("localhost", 3000);
r = new BufferedReader(new InputStreamReader(s.getInputStream()));
w = new PrintWriter(s.getOutputStream(), true);
BufferedReader con = new BufferedReader(new InputStreamReader(System.in));
Thread t1 = new Thread(){
public void run(){
handle_read();
}
};
Thread t2 = new Thread(){
public void run(){
handle_write();
}
};
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Exiting .... ");
}
catch (Exception err)
{
System.err.println(err);
}
}
public static void handle_read(){
while(true){
try{
String line = r.readLine();
System.out.println(line);
}
catch(Exception e){
System.err.println(e);
}
}
}
public static void handle_write(){
while(true){
try{
Scanner scan = new Scanner(System.in);
String s = scan.next();
w.println(s);
}
catch(Exception e){
System.err.println(e);
}
}
}
}
谢谢!
答案 0 :(得分:1)
您正在发送此消息:
buf[0] = 's';
buf[1] = 't';
buf[2] = 'a';
buf[3] = 'r';
buf[4] = 't';
buf[5] = 0;
然后您正在阅读此代码
String line = r.readLine();
这似乎不匹配。你没有发送一行,但是你正试图读一行。
使用换行符'\ n'
结束您发送的讯息