问一个关于socket的问题
http://bbs.csdn.net/topics/392186524
这是我上次遇到的问题,后来发现一部分原因,但是还是很疑惑,希望大家可以帮助我解决疑惑。
上次的问题后来我发现原因是,客户端一连上来有发送数据,而我没有去read客户端发送的数据,然后去调用两次write之后去close(fd)导致服务端只会发送第一次调用write的的数据,然后我把close(fd)去掉发现是可以将两次write的数据都发送出去,或者先将客户端发来的数据都读取完(必须读取完,读取一半也不行)然后close掉也是可以的。但是这两者都有弊端啊,第一个你不close(fd)或导致随着连接次数的增加,fd会持续增长,然后会被吃光。第二种,如果你读到一半,发现客户端发来的数据有问题,不想读了直接返回数据给客户端这种就做不到了啊。一开始我以为是epoll的问题,后来我直接用最直接的方式去做测试也不行。难道不读客户端发来的数据会影响写操作吗?下面是我写的测试代码:
服务端是用Linux c写的
客户端测试代码用的是java
大家帮忙看看啊 ,谢谢了!
这是我上次遇到的问题,后来发现一部分原因,但是还是很疑惑,希望大家可以帮助我解决疑惑。
上次的问题后来我发现原因是,客户端一连上来有发送数据,而我没有去read客户端发送的数据,然后去调用两次write之后去close(fd)导致服务端只会发送第一次调用write的的数据,然后我把close(fd)去掉发现是可以将两次write的数据都发送出去,或者先将客户端发来的数据都读取完(必须读取完,读取一半也不行)然后close掉也是可以的。但是这两者都有弊端啊,第一个你不close(fd)或导致随着连接次数的增加,fd会持续增长,然后会被吃光。第二种,如果你读到一半,发现客户端发来的数据有问题,不想读了直接返回数据给客户端这种就做不到了啊。一开始我以为是epoll的问题,后来我直接用最直接的方式去做测试也不行。难道不读客户端发来的数据会影响写操作吗?下面是我写的测试代码:
服务端是用Linux c写的
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
int main(void) {
struct sockaddr_in server_addr;
int err = 0;
int ss = socket(AF_INET, SOCK_STREAM, 0);
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr("0.0.0.0");
server_addr.sin_port = htons(8080);
err = bind(ss, (struct sockaddr *)&server_addr, sizeof(server_addr));
if(err < 0) {
printf("bind error\n");
return -1;
}
listen(ss, 10);
if(err < 0) {
printf("bind error\n");
return -1;
}
socklen_t addrlen;
while(1) {
int fd = accept(ss, (struct sockaddr*)&addrlen, &addrlen);
//char buffer[1024];
//read(s, buffer, 1024); 这个地方先注释掉就会发现第二次的write写不出去
int len = write(fd, "hello", 5);
int len2 = write(fd, "world", 5);
printf("fd:%d\n", fd);
printf("len:%d\n", len);
printf("len2:%d\n", len2);
printf("===========================\n");
close(fd);//把这句注释就能将第二次write的数据写出去
}
return 0;
}
客户端测试代码用的是java
package com.example.test;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class SocketTest {
public static void main(String[] args) {
for (int i = 0; i < 100; i++){
socketTest();
}
}
public static void socketTest() {
Socket socket = null;
try {
socket = new Socket("192.168.1.151", 8080);
InputStream is = socket.getInputStream();
byte[] buffer = new byte[128];
OutputStream os = socket.getOutputStream();
os.write("hello world".getBytes());
int len = is.read(buffer, 0, 5);
is.read(buffer, len, 5);
System.out.println("len:" + len);
System.out.println(new String(buffer));
} catch (IOException e) {
e.printStackTrace();
} finally {
if(socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
大家帮忙看看啊 ,谢谢了!
...全文
相关推荐
Socket聊天程序(一个服务端,多个客户端)
Socket聊天程序是一个基于C#编程语言实现的网络通信应用,它允许一个服务端与多个客户端进行实时交互。
Socket通信,通过异步,解决粘包问题
在TCP/IP协议栈中,Socket接口提供了应用层与传输层之间的接口,使得应用程序能够利用TCP或UDP等传输层协议进行数据交换。在Socket通信中,"粘包"问题是一个常见的挑战。
vue-socket.io接收不到数据问题的解决方法
这表明服务器正在正确地发送数据,而问题出在vue-socket.io的使用上。通过深入研究,发现`this`对象上由于vue-socket.io的集成增加了一个名为`sockets`的属性。
vue-socket.io跨域问题有效解决方法
跨域是浏览器为了安全原因而设置的一种限制,它不允许从一个源(domain)加载资源到另一个源,除非两个源之间有明确的允许跨域的策略。
一个拦截socket 的hook
本文档探讨的是如何使用Windows系统下的套接字(Socket)技术实现网络数据包的截取,通过编写一个基于BCB(Borland C++ Builder)封装的动态链接库(DLL),实现对特定网络通


