采用tcp协议,使用socket编程,编写程序完成客户端发送消息给服务端,服务端接到消息后,再发
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了采用tcp协议,使用socket编程,编写程序完成客户端发送消息给服务端,服务端接到消息后,再发相关的知识,希望对你有一定的参考价值。
给客户端
参考技术A 服务端代码:/*server.c*/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netinet/in.h>
#define PORT 4321
#define BUFFER_SIZE 1024
#define MAX_QUE_CONN_NM 5
int main()
struct sockaddr_in server_sockaddr, client_sockaddr;
int sin_size, recvbytes;
int sockfd, client_fd;
char buf[BUFFER_SIZE];
/*建立socket连接*/
if ((sockfd = socket(AF_INET,SOCK_STREAM,0))== -1)
perror("socket");
exit(1);
printf("Socket id = %d\n",sockfd);
/*设置sockaddr_in 结构体中相关参数*/
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(PORT);
server_sockaddr.sin_addr.s_addr = INADDR_ANY;
bzero(&(server_sockaddr.sin_zero), 8);
int i = 1;/* 使得重复使用本地地址与套接字进行绑定 */
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
/*绑定函数bind*/
if (bind(sockfd, (struct sockaddr *)&server_sockaddr, sizeof(struct sockaddr))== -1)
perror("bind");
exit(1);
printf("Bind success!\n");
/*调用listen函数*/
if (listen(sockfd, MAX_QUE_CONN_NM) == -1)
perror("listen");
exit(1);
printf("Listening....\n");
/*调用accept函数,等待客户端的连接*/
if ((client_fd = accept(sockfd, (struct sockaddr *)&client_sockaddr, &sin_size)) == -1)
perror("accept");
exit(1);
/*调用recv函数接收客户端的请求*/
memset(buf , 0, sizeof(buf));
if ((recvbytes = recv(client_fd, buf, BUFFER_SIZE, 0)) == -1)
perror("recv");
exit(1);
printf("Received a message: %s\n", buf);
if ((sendbytes = send(sockfd, buf, strlen(buf), 0)) == -1)
perror("send");
exit(1);
close(sockfd);
exit(0);
客户端:
/*client.c*/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#define PORT 4321
#define BUFFER_SIZE 1024
int main(int argc, char *argv[])
int sockfd, sendbytes;
char buf[BUFFER_SIZE];
struct hostent *host;
struct sockaddr_in serv_addr;
if(argc < 3)
fprintf(stderr,"USAGE: ./client Hostname(or ip address) Text\n");
exit(1);
/*地址解析函数*/
if ((host = gethostbyname(argv[1])) == NULL)
perror("gethostbyname");
exit(1);
memset(buf, 0, sizeof(buf));
sprintf(buf, "%s", argv[2]);
/*创建socket*/
if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
perror("socket");
exit(1);
/*设置sockaddr_in 结构体中相关参数*/
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(serv_addr.sin_zero), 8);
/*调用connect函数主动发起对服务器端的连接*/
if(connect(sockfd,(struct sockaddr *)&serv_addr, sizeof(struct sockaddr))== -1)
perror("connect");
exit(1);
/*发送消息给服务器端*/
if ((sendbytes = send(sockfd, buf, strlen(buf), 0)) == -1)
perror("send");
exit(1);
if ((recvbytes = recv(sockfd, buf, BUFFER_SIZE, 0)) == -1)
perror("recv");
exit(1);
close(sockfd);
exit(0);
追问
这个c的我想求java的
追答请看博客
http://www.jb51.net/article/45024.htm
基于 TCP/IP 协议的网络编程
在说明基于 TCP/IP 协议的网络编程之前,先来了解一下 Socket(网络套接字):- 利用套接字(Socket)开发网络应用程序早已被广泛的采用,以至于成为事实上的标准
- 通信的两端都要有 Socket,是两台机器间通信的端点(API 原话)
- 网络通信其实就是 Socket 间的通信
- Socket 允许程序把网络连接当成一个流,数据在两个 Socket 间通过 IO 传输
- 一般主动发起通信的应用程序属客户端,等待通信请求的为服务端
网络编程某种程度上可以称作“Socket 编程”
TCP/IP 编程,简单模拟客户端与服务端之间的交互(先开 Server 再开 Client):
public class TestTCP {
@Test
public void client() {
Socket socket = null;
OutputStream os = null;
try {
// 创建 Socket 对象以指明目标 Server 的 IP 和端口
socket = new Socket("127.0.0.1", 9876);
// 调用该套接字对象的 getOutputStream()方法返回 OutputStream 对象以写出数据
os = socket.getOutputStream();
// 后面实际就是 IO 流的应用
os.write("This is the message sent by client".getBytes());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// socket 也是稀有资源,记得及时关闭
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Test
public void server() {
ServerSocket ss = null;
Socket socket = null;
InputStream is = null;
try {
// 创建 ServerSocket 对象指明开放那个端口作为传输端口
ss = new ServerSocket(9876);
// 调用 accept()方法,返回一个 Socket 对象,监听 ServerSocket 对应的端口并且接受对该端口的连接
socket = ss.accept();
// 调用该套接字对象的 getInputStream()方法返回 InputStream 对象以写入从 client 接收到的数据
is = socket.getInputStream();
// 后面实际就是 IO 流的应用
byte[] b = new byte[10];
int len;
while ((len = is.read(b)) != -1) {
// 打印字节流
System.out.print(new String(b, 0, len));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
若要实现多步交互,注意 Socket 方法的阻塞性问题,如果一直监听端口,就不能执行后续代码,故记得调用相关 shutdown 方法以关闭监听,以下例子修改自上例,实现在 Server 端收到字节流后,返回给 Client 一条反馈信息:
public class TestTCP {
@Test
public void client() {
Socket socket = null;
OutputStream os = null;
InputStream is = null;
try {
// 创建 Socket 对象以指明目标 Server 的 IP 和端口
socket = new Socket("127.0.0.1", 9876);
// 调用该套接字对象的 getOutputStream()方法返回 OutputStream 对象以写出数据
os = socket.getOutputStream();
// 后面实际就是 IO 流的应用
os.write("This is the message sent by client".getBytes());
// ----------update----------
// 显式的禁用此套接字的输出流
socket.shutdownOutput();
// 接受反馈
is = socket.getInputStream();
byte[] b = new byte[10];
int len;
while ((len = is.read(b)) != -1) {
System.out.print(new String(b, 0, len));
}
// ----------update----------
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// socket 也是稀有资源,记得及时关闭
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Test
public void server() {
ServerSocket ss = null;
Socket socket = null;
InputStream is = null;
OutputStream os = null;
try {
// 创建 ServerSocket 对象指明开放那个端口作为传输端口
ss = new ServerSocket(9876);
// 调用 accept()方法,返回一个 Socket 对象,监听 ServerSocket 对应的端口并且接受对该端口的连接
socket = ss.accept();
// 调用该套接字对象的 getInputStream()方法返回 InputStream 对象以写入从 client 接收到的数据
is = socket.getInputStream();
// 后面实际就是 IO 流的应用
byte[] b = new byte[10];
int len;
while ((len = is.read(b)) != -1) {
// 打印字节流
System.out.print(new String(b, 0, len));
}
// ----------update----------
// 反馈一条消息给 Client
os = socket.getOutputStream();
os.write("I have received your message".getBytes());
// ----------update----------
} catch (IOException e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
以上是关于采用tcp协议,使用socket编程,编写程序完成客户端发送消息给服务端,服务端接到消息后,再发的主要内容,如果未能解决你的问题,请参考以下文章